方法调用模式(Method Invocation Pattern)
在面向对象程序设计中,当函数(Function)作为对象属性时被称为方法(Method)。方法被调用时 this
会被绑定到对应的对象。在 JavaScript 中有两种语法可以完成方法调用。
当一个函数被保存为对象的一个属性时,我们称它为一个方法。当一个方法被调用时,this
被绑定到该对象。如果调用表达式包含一个提取属性的动作,那么它就是被当做一个方法来调用。
var foo = {fn: function(){console.log(1);}};foo.fn();// 1
方法可以使用 this
访问自己所属的对象,所以它能从对象中取值或对对象进行修改。this
到对象的绑定发生在调用的时候。通过 this
可取得它们所属对象的上下文的方法称为公共方法。
var foo = {id: 1,fn: function(){return this;},update: function(){this.id = 2;}};console.log(foo.fn().id);// 1foo.update();console.log(foo.fn().id);// 2
任何函数只要作为方法调用实际上都会传入一个隐式的实参——这个实参是一个对象,方法调用的母体就是这个对象,通常来讲,基于那个对象的方法可以执行多种操作,方法调用的语法已经很清晰地表明了函数将基于一个对象进行操作。
rect.setSize(width, height);setRectSize(rect, width, height);
假设上面两行代码的功能完全一样,它们都作用于一个假定的对象 rect
。可以看出,第一行的方法调用语法非常清晰地表明这个函数执行的载体是 rect
对象,函数中的所有操作都将基于这个对象。
this
和变量不同,关键字 this
没有作用域的限制,嵌套的函数不会从调用它的函数中继承 this
。
this
的值指向 调用它的对象。this
值不是 全局对象(非严格模式下)就是 undefined
(严格模式下)。var foo = {fn: function(){function n(){return this;}return n();}}console.log(foo.fn()); // window
var foo = {fn: function(){function n(){'use strict';return this;}return n();}}console.log(foo.fn()); // undefined
如果想访问这个外部函数的 this
值,需要将 this
的值保存在一个变量里,这个变量和内部函数都同在一个作用域内。通常使用变量 self
或 that
来保存 this
。
const foo = {fn: function(){const self = this;console.log(this === foo);//truefunction n(){console.log(this === foo);//falseconsole.log(self === foo);//truereturn self;}return n();}}console.log(foo.fn() === foo);// true