在下面的代码中,我无法理解一些关于this
的事情
function Stack() {
let items = [];
push = function(element){
items.push(element);
};
this.pop = function(){
return items.pop(); // removes and returns the element.
};
}
let stk= new Stack();
stk.push(); // 1
stk.pop(); // no error
- 抛出
stk.push
不是一个函数。 为什么 ? 为什么缺乏this
会阻止推送方法。 - 为什么一定要
new Stack()
,为什么不能let stk= Stack()
识别函数内部的方法?
由于我正在实例化 Stack 函数,无论方法是否用this
声明,stkvar 都应该能够访问函数,不是吗?
让我们看两个例子:
push = function() { /*...*/ }
和
var push = function() { /*...*/ }
在第一个中,push
是一个全局变量。 所以我们没有定义任何类似的东西Stack.push
它是push
. 所以文你做:
push();
它被执行了,当然失败了!
在第二个中,变量的作用域在本地,这意味着它只能在函数内部使用Stack
。
因此,在这种情况下,推送在 Stack 之外的任何地方都是未定义的。
没有定义push
和Stack.push
或stk.push
。
现在让我们看看其他选项:
this.push = function() { /*...*/ }
这将定义当前对象的字段push
。
让我们澄清一下:
let Stack = function() {
this.push = function() { console.log("Hello!"); }
console.log(this);
};
Stack();
所以我们得到的是:
窗口 {框架: 窗口, 帖子消息: ƒ, 模糊: ƒ, 焦点: ƒ,关闭: ƒ, ...}
等什么?这意味着函数的上下文(this
)是Window
对象。 所以在这种情况下(如果我们在浏览器中工作),我们再次定义了全局 可变push
!
let Stack = function() {
this.push = function() { console.log("Hello!"); }
};
Stack();
push();
输出
你好!
所以现在要拯救的是new
关键词。 基本上Mozilla文档说:
当执行新的 Foo(...) 代码时,会发生以下情况:
创建一个新对象,继承自 Foo.prototype。 构造函数 Foo 使用指定的参数调用,并且 这绑定到新创建的对象。 新Foo相当于新Foo(), 即,如果没有指定参数列表, Foo 的调用没有参数。
构造函数返回的对象将成为整个新表达式的结果。如果构造函数未显式返回对象,则改用在步骤 1 中创建的对象。
(通常构造函数不返回值,但如果它们想要重写正常的对象创建过程,则可以选择这样做。
就是这样! 新关键字将this
绑定到newly created object
。
所以当我们执行
new Stack()
this
关键字是指我们创建的对象!这就是为什么当我们分配时
this.push = /* Something */
可以理解为以下代码:
// Create new stack object
var stack = /* This is done by the 'new' keyword */
// Run our code
stack.push = /* Something */
基本上就是这样!希望它对你有所帮助:)
函数是一个对象,这是指对象的特定实例。
如果函数中有一个没有this的函数,则该函数是该函数的本地函数。
有了这个,内部函数就变成了对象的方法,可以调用它来执行一些动作。