
2025-02-04 日报 Day87

今日的鸡汤
在这个世上,一个人想要成功,就一定要去做难一点的事。比如不断地学习,不断地成长,不断地进步。
今日学习内容
1、JS 红皮书 P300-303 第十章:函数
今日笔记
1、this: 另一个特殊的对象是 this,它在标准函数和箭头函数中有不同的行为。
在标准函数中,this 引用的是把函数当成方法调用的上下文对象,这时候通常称其为 this 值(在网页的全局上下文中调用函数时,this 指向 windows)。在箭头函数中,this引用的是定义箭头函数的上下文。下来看下面的例子:
1 | window.color = 'red'; |
有读者知道,在事件回调或定时回调中调用某个函数时,this 值指向的并非想要的对象。此时将回调函数写成箭头函数就可以解决问题。这是因为箭头函数中的 this 会保留定义该函数时的上下文:
1 | function King() { |
2、caller: ECMAScript 5 也会给函数对象上添加一个属性:caller。虽然 ECMAScript 3 中并没有定义,但所有浏览器除了早期版本的 Opera 都支持这个属性。这个属性引用的是调用当前函数的函数,或者如果是在全局作用域中调用的则为 null。比如:
1 | function outer() { |
以上代码会显示 outer()函数的源代码。这是因为 ourter()调用了 inner(),inner.caller指向 outer()。如果要降低耦合度,则可以通过 arguments.callee.caller 来引用同样的值:
1 | function outer() { |
3、new.target: ECMAScript 中的函数始终可以作为构造函数实例化一个新对象,也可以作为普通函数被调用。ECMAScript 6 新增了检测函数是否使用 new 关键字调用的 new.target 属性。如果函数是正常调用的,则 new.target 的值是 undefined;如果是使用 new 关键字调用的,则 new.target 将引用被调用的构造函数。
1 | function King() { |
4、函数属性与方法: ECMAScript 中的函数是对象,因此有属性和方法。每个函数都有两个属性:length 和 prototype。其中,length 属性保存函数定义的命名参数的个数,如下例所示:
1 | function sayName(name) { |
prototype 属性也许是 ECMAScript 核心中最有趣的部分。prototype 是保存引用类型所有实例方法的地方,这意味着 toString()、valueOf()等方法实际上都保存在 prototype 上,进而由所有实例共享。这个属性在自定义类型时特别重要。(相关内容已经在第 8 章详细介绍过了。)在 ECMAScript 5中,prototype 属性是不可枚举的,因此使用 for-in 循环不会返回这个属性。
函数还有两个方法:apply()和 call()。这两个方法都会以指定的 this 值来调用函数,即会设置调用函数时函数体内 this 对象的值。apply()方法接收两个参数:函数内 this 的值和一个参数数组。第二个参数可以是 Array 的实例,但也可以是 arguments 对象。来看下面的例子:
1 | function sum(num1, num2) { |
到底是使用 apply()还是 call(),完全取决于怎么给要调用的函数传参更方便。如果想直接传 arguments对象或者一个数组,那就用 apply();否则,就用 call()。
apply()和 call()真正强大的地方并不是给函数传参,而是控制函数调用上下文即函数体内 this值的能力。考虑下面的例子:
1 | window.color = 'red'; |
使用 call()或 apply()的好处是可以将任意对象设置为任意函数的作用域,这样对象可以不用关心方法。
ECMAScript 5 出于同样的目的定义了一个新方法:bind()。bind()方法会创建一个新的函数实例,其 this 值会被绑定到传给 bind()的对象。比如:
1 | window.color = 'red'; |