资讯专栏INFORMATION COLUMN

JavaScript红宝书笔记(七)---Function类型

cyrils / 698人阅读

摘要:函数实际上是对象。所以需要消除这种紧耦合。函数内部属性引用的是函数据以执行的环境对象或者也可以说是值函数的名字仅仅是一个包含指针的变量而已。因此,即使是在不同的环境中执行,全局的函数与函数指向的仍然是同一个函数。

1.函数实际上是对象。每个函数都是 Function 类型的实例,而且都与其他引用类型一样具有属性和方法

2.由于函数名仅仅是指向函数的指针,因此函数名与包含对象指针的其他变量没有什么不同

function sum(num1, num2){
    return num1 + num2;
}
alert(sum(10,10)); //20
var anotherSum = sum;
alert(anotherSum(10,10)); //20
sum = null;
alert(anotherSum(10,10)); //20

3.ECMAScript中函数没有重载

4.函数声明和函数表达式的区别:解析器会率先读取函数声明,并使其在执行任何代码之前可用(可以访问);至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解释执行

alert(sum(10,10));
function sum(num1, num2){
    return num1 + num2;
}                              //函数声明提升,正常执行

alert(sum(10,10));
var sum = function(num1, num2){
    return num1 + num2;
};                            //报错

5.作为值得函数:不仅可以像传递参数一样把一个函数传递给另一个函数,而且可以将一个函数作为另一个函数的结果返回;仅使用函数名可以访问函数的指针而不执行函数。

function add10(num){
    return num + 10;
}
var result1 = callSomeFunction(add10, 10);
alert(result1); //20

6.函数内部属性arguments

arguments它是一个类数组对象,包含着传入函数中的所有参数,它还包含一个属性交callee,该属性是一个指针,指向拥有这个 arguments 对象的函数。callee属性可以用来解耦合。

function factorial(num){
if (num <=1) {
    return 1;
} else {
    return num * factorial(num-1)        //利用factorial函数名回调递归
    }
}

这样做法如果之后factorial赋值给别的变量,然后又重新赋值一个函数给factorial。那么别的变量并不会调用到原本的递归函数,而是调用到factorial新赋值的函数。所以需要消除这种紧耦合。

function factorial(num){
    if (num <=1) {
        return 1;
    } else {
        return num * arguments.callee(num-1)
    }
}

var trueFactorial = factorial;

factorial = function(){
    return 0;
};

alert(trueFactorial(5)); //120
alert(factorial(5)); //0

7.函数内部属性this
this引用的是函数据以执行的环境对象——或者也可以说是 this 值

window.color = "red";
var o = { color: "blue" };
function sayColor(){
    alert(this.color);
}
sayColor(); //"red"
o.sayColor = sayColor;
o.sayColor(); //"blue"

ps:函数的名字仅仅是一个包含指针的变量而已。因此,即使是在不同的环境中执行,全局的sayColor()函数与o.sayColor()函数指向的仍然是同一个函数。

8.函数都包含的属性与length和protoType。
length是函数接收的命名参数个数;
protoType是保存他们所有实例方法的真正所在,例如valueOf(),toString(),只不过是通过各自对象的实例访问。另外,prototype 属性是不可枚举的,因此使用 for-in 无法发现。

9.每个函数都包含两个非继承而来的方法:apply()和 call()。这两个方法的用途都是在特定的作用域中调用函数
apply()方法接收两个参数:一个是在其中运行函数的作用域,另一个是参数数组

function sum(num1, num2){
    return num1 + num2;
}
function callSum1(num1, num2){
    return sum.apply(this, arguments); // 传入 arguments 对象
}
function callSum2(num1, num2){
    return sum.apply(this, [num1, num2]); // 传入数组
}
alert(callSum1(10,10)); //20
alert(callSum2(10,10)); //20

call()方法与 apply()方法的作用相同,它们的区别仅在于接收参数的方式不同。传递给函数的参数必须逐个列举出来。

function sum(num1, num2){
    return num1 + num2;
}
function callSum(num1, num2){
    return sum.call(this, num1, num2);
}
alert(callSum(10,10)); //20

10.传递参数并非 apply()和 call()真正的用武之地;它们真正强大的地方是能够扩充函数赖以运行的作用域

window.color = "red";
var o = { color: "blue" };
function sayColor(){
    alert(this.color);
}
sayColor(); //red
sayColor.call(this); //red
sayColor.call(window); //red
sayColor.call(o); //blue

使用 call()(或 apply())来扩充作用域的最大好处,就是对象不需要与方法有任何耦合关系。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/105247.html

相关文章

  • Effective JavaScript读书笔记(一)

    摘要:如果为假值,不传或者传入,函数都会返回但是,传入这个值是完全有可能的,所以这种判断形势是不正确的或者使用来判断也可以原始类型优于封装类型对象拥有六个原始值基本类型布尔值,数字,字符串,,和对象。 作为一个前端新人,多读书读好书,夯实基础是十分重要的,正如盖楼房一样,底层稳固了,才能越垒越高。从开始学习到现在,基础的读了红宝书《JavaScript高级程序设计》,犀牛书《JavaScri...

    zhoutao 评论0 收藏0
  • JavaScript宝书笔记(四)---变量、作用域和内存问题

    摘要:在操作对象时,实际上是在操作对象的引用而不是实际的对象。为此,引用类型的值是按引用访问的。标记清除是目前主流的垃圾收集算法,这种算法的思想是给当前不使用的值加上标记,然后再回收其内存 1.在操作对象时,实际上是在操作对象的引用而不是实际的对象。为此,引用类型的值是按引用访问的。 2.当从一个变量向另一个变量复制引用类型的值时,两个变量实际上将引用同一个对象,因此,改变其中一个变量,就会...

    imtianx 评论0 收藏0
  • JavaScript宝书笔记(一)---JS概述、变量及基本数据类型

    摘要:是一个数值可以被转换成数值不能转换成数值可以被转换成数值十六进制数八进制数十进制数十六进制数可以避免,无法使用方法转换成字符串的情况 1.JavaScript由三个部分组成:ECMAScript(提供核心语言功能)、DOM(文档对象模型,提供访问和操作网页内容的方法和接口)、BOM(浏览器对象模型,提供与浏览器交互的方法和接口) 2.JavaScript概念:是一种专为与网页交互而设计...

    sevi_stuo 评论0 收藏0
  • JavaScript宝书笔记(五)---引用类型

    摘要:在通过对象字面量定义对象时,实际上不会调用构造函数相当于因为是松散类型数据,所以类型也拥有着同样的特性。数组的每一项可以保存任何类型的数据,且数组的大小是可以动态调整的。对数组中的每一项运行给定函数,返回该函数会返回的项组成的数组。 1.在通过对象字面量定义对象时,实际上不会调用 Object 构造函数 var person = { name : Nicholas, a...

    G9YH 评论0 收藏0
  • JavaScript宝书笔记(六)---RegExp类型

    摘要:第二个循环使用构造函数在每次循环中创建正则表达式。布尔值,表示是否设置了标志。整数,表示开始搜索下一个匹配项的字符位置,从算起。正则表达式的字符串表示,按照字面量形式而非传入构造函数中的字符串模式返回。 1.var someDate = new Date(Date.parse(May 25, 2004));可用来计算时间差 //取得开始时间 var start = Date.now()...

    eternalshallow 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<