关于JavaScript的this
来源:互联网 发布:拼接屏软件 编辑:程序博客网 时间:2024/05/29 04:45
this这个概念在很多流行语言里都有,大家的定义都很一致,也就是运行时的实例本身,但是在JavaScript这里就不一样了。this是函数里的当前引用(全部代码你可以看成是在宿主对象window下的一个大匿名函数里,就像require的实现那样),有一种说法是JavaScript里的this是调用者对象,但这个并不贴切。比如下面的代码:
var o = {};
o.f = function() {
var ff = function() {
console.log(this);
};
ff();
console.log(this);
};
o.f(); // window 对象 & o 对象
首先, 在JavaScript的运行时里,一切存在单位皆是对象(实例)。这些对象不是孤立存在的,它们之间有两种类型的关系。一类是对象能力的回溯关系(原型链);一类是对象引用的组织关系(对象属性),也就是摆放在哪儿。而this指向的正是其摆放位置对象。比如上例中的f在对象o里,里面的this就是o。o和ff没有明确指定摆放位置,在标准模式下它们会被摆放在宿主对象window里,this自然就是window了。那如果我们执行如下代码会怎么样呢:
var of = o.f;
of(); // window & window
of和o.f是同一个函数的两个引用,这里可以看出this即是引用位置对象。继续代码:
o.oo = {
g: function() {
console.log(this);
}
};
o.oo.g(); // o.oo 对象
不用解释了吧。继续代码:
var f1 = function() {
console.log(this);
};
var o1 = new f1(); // f1 对象
这个怎么理解呢?我们把引擎的动作用如下的伪代码描述:
// 伪代码
var f1 = function() {
console.log(this);
};
var o1 = {};
o1.__proto__ = {
constructor: f1
};
o1.constructor();
不用解释了吧。继续代码:
o.f2 = function() {
var ff = () => {
console.log(this);
};
ff();
console.log(this);
};
o.f2(); // 两个 都是 对象 o
Why? 这个o.f2和之前的o.f的区别就是把函数的书写形式变了一下,箭头函数里输出的为什么不是window呢?“箭头函数”的学名叫lambda表达式(lambda expression),它像函数一样拥有一个独立的作用域,但是并不具备函数的各种特性。所以箭头函数里的this也就等同于此“函数”所在位置的this。OK,继续code:
o.oo.g1 = function() {
setTimeout(this.g, 1000); // call o.oo.g()
};
o.oo.g1(); // window
这里不会像直接执行o.oo.g()那样打印o.oo对象了,因为setTimeout向宿主环境(window)注册了一个执行体函数,window会把这个执行体保存在自己的一个匿名属性里,将来由宿主对象执行时打印的就是window。但是下面这个定时器又不一样了:
o.oo.g2 = function() {
console.log(this);
setTimeout(()=>{ console.log(this); }, 1000);
};
o.oo.g2(); // 两个o.oo 对象
这个定时器执行的时候为什么不是打印window呢?前书说过,lambda表达式不具备函数特性,也不存在自己的this,这里这个this其实是因为闭包特性顺带过来的。如有疑问可以换一个普通变量看看即知。
诸如call、apply、bind这些都是人工指定this,当然您指啥就是啥。如果指定对象是undefine或者null之类,则仍然遵守前述规则指向宿主对象window(正常模式)。
总结:
一、以上论述纯属推断,并未参考源代码的实际实现。因此如有雷同,纯属巧合 。我们从正向和反向看待同一个事物的时候,有时能看到不同的东西。
二、以上推断出于技术研究的动机,若出于实用目的,我认为可以用更加常规的代码组织方式,并不必要把这些东西剥得这么清楚。就如同我们想写一封信,并不需要会写四种“回”字。
诸如call、apply、bind这些都是人工指定this,当然您指啥就是啥。如果指定对象是undefine或者null之类,则仍然遵守前述规则指向宿主对象window(正常模式)。
总结:
一、以上论述纯属推断,并未参考源代码的实际实现。因此如有雷同,纯属巧合 。我们从正向和反向看待同一个事物的时候,有时能看到不同的东西。
二、以上推断出于技术研究的动机,若出于实用目的,我认为可以用更加常规的代码组织方式,并不必要把这些东西剥得这么清楚。就如同我们想写一封信,并不需要会写四种“回”字。
0 0
- 关于JavaScript的this
- 关于javascript的this
- 关于JavaScript的this
- 关于javascript的this的几道题
- 关于javascript中this的理解
- JavaScript 中 关于 this 的学习笔记
- 关于javascript的this指向问题
- JavaScript中关于this关键字的详解
- javascript关于this,call,apply的小结
- 关于JavaScript中this关键字的理解
- 关于JavaScript的prototype、__proto__、constructor、this
- 关于JavaScript中this的一些理解
- javaScript中关于this的指向
- 关于JavaScript中的this
- JavaScript 关于this对象
- JavaScript笔记:关于this
- 关于javascript中的this
- 关于javascript中的this
- u3d+Litjson保存数据到安卓端
- 知识记录三:自定义Dialog
- javascript之window对象
- HTML DOM Element 对象
- 微信小程序-设置启动页面
- 关于JavaScript的this
- HTML DOM 元素对象
- Linux-使用 Find 命令找到那些需要清理的文件
- 寒假集训日常!
- 飞机大战
- BZOJ2002: [Hnoi2010]Bounce 弹飞绵羊
- Swift 学习笔记 [2] 类 结构体 枚举
- 辣椒炸弹
- C# Timer