以下是简单的代码:
var name = " Window";
var o = {
name : "Object",
getName : function(){
return function(){
return this.name;
};
}
};
var a = o.getName;
a()();
var c = o.getName()();
var o1 = {
name : "My Object",
getName : function(){
var that = this;
return function(){
return that.name;
};
}
};
var d = o1.getName()();
var e = o1.getName;
e()();
请问1 :var c = o.getName()()中在运行o.getName()时,this的指向还是o,为什么o.getName()()时,this的指向就成了window?
请问2 :var a = o.getName;a()();这种方式和o.getName()()有什么区别?
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
当一个函数作为方法调用时,其this指针指向调用它的对象,否则this为undefined(strict mode)或window(浏览器),global(node)
在
o.getName()()中,getName作为o的方法调用,其this指针就指向了o,所以o.getName()执行时this指向o。然后
o.getName()返回一个函数,o.getName()()就等价于(o.getName())(),可以看到新的函数没有作为任何一个对象的方法调用,只是孤立的作为函数调用,其this指针就指向window。如果像
var a = o.getName; a()();这样将getName提取出来再调用,赋值给a的只是getName的函数本身,并不包括调用它的环境。a()运行时a只是一个函数,并没有作为任何对象的方法,其this指针就已经指向window了。1.
o.getName()()拆开是
(o.getName())()第一步是o.getName(),是对对象方法的调用,this指向对象。
第二步是
(function()return this.name;};)()对匿名函数的直接调用,非严格模式this就是window。2.
var a = 后面语句的返回值,即将=右侧语句执行的返回值赋值给a。o.getName()()就是调用一下,没有接收返回值。两者目的不一样。
写在前面
先要了解词法作用域 动态作用域 箭头函数,才能明白 this本质。
词法作用域 动态作用域
箭头函数
箭头函数就是个简写形式的函数表达式,并且它拥有词法作用域的this值(即不会新产生自己作用域下的this, arguments, super 和 new.target 等对象)。此外,箭头函数总是匿名的。
箭头函数则会捕获其所在上下文的 this 值,作为自己的 this 值,因此下面的代码将如期运行。
使用 new 操作符 (箭头函数不能用作构造器,和 new 一起用就会抛出错误。)
箭头函数,就是没有自身this属性的函数。直接在它的静态作用域找最近的函数的this.
非严格模式,函数this初始化为window/global;严格模式,函数初始化为undefined.(当然,普通函数this有绑定(指向引用)时,内部的箭头函数this指向便是此引用)
有空也可以看看这个C程序函数栈作用机理
进入函数时,最右边的参数arg2先入栈,按照C函数的值传递特性,此时传入的是string的副本,即arg2也是一个地址,指 向0xCFFFFFF0。然后arg1入栈,接着是返回地址入栈。因为arg2是4个字节,arg1也是一个字符串常量的地址,也是4个字 节。可以看到,此时的0xCFFFFFF0地址已经被返回地址覆盖掉了,而这个地址正是上次调用时的数组p的起始位置,并且 main中的局部变量string和printf的第二个参数arg2都指向这个地址,但此时该地址中的的值已经不是'h'了,同样的,因 为printf要为其局部变量分配内存,hello world的12个字节全部被覆写。
综上所述,printf在一进入的瞬间,哪怕不执行任何代码,原hello world的空间就被覆盖了,自然也不会得到正确的输 出。得到的全是随机的乱码。实际上也不能简单说是随机的,因为返回地址,printf的局部变量都是确定的,只是把这些 地址,局部变量都当成char输出时,肯定是乱码了,但肯定是确定的乱码。
javascript 执行环境,变量对象,作用域链
作用域链Scope其实就是对执行上下文EC中的变量对象VO|AO有序访问的链表
一系列活动的执行上下文从逻辑上形成一个栈