这篇文章主要知识点是关于javascript、this、的内容,如果大家想对相关知识点有系统深入的学习,可以参阅以下电子书
this 的定义
表示当前执行代码的环境对象
因此可将 this 的剖析分为“全局环境” 和 “函数环境” 两种类型的环境对象
全局环境
console.log(this === window); // true var a = 10; console.log(this.a); // 10
函数环境
在函数内部,this 的取值取决于函数被调用时的运行环境。
这里涉及到内存里的数据结构相关的知识点,当我们定义以下字面量对象时会发生一系列的关联关系
var obj = { name: 'Tom' };
javascript 引擎会先在内存中生成 { name: 'Tom' } 对象,接着再把这个对象的内存地址赋值给 obj 变量,所以 obj 变量保存的只是一个内存地址而已,如果要获取 obj.name,javascript 引擎会先从 obj 变量中拿到内存地址,然后从该地址中获取原始对象,再返回 name 属性。
而属性值为函数时,该函数会被保存在内存中,然后将该内存地址赋值给该属性,因此该地址赋值给不同环境执行时它的作用域是不一样的,而 this 对象就是指向函数当前的执行环境对象,执行环境是会在 Event Loop(事件循环)过程中变化的,因此 this 在函数环境下是属于运行时的。
var name = 'Tom'; var obj = { name: 'Iceberg', say: function() { console.log('my name is ' + this.name); }, sub: { say: function() { console.log('my name is ' + this.name); } } }; obj.say(); // my name is Iceberg obj.sub.say() // my name is undefined; var say = obj.say; say(); // my name is Tom;
上面的例子说明 obj.say() 执行环境为 obj 对象,而 obj.sub.say() 的执行环境却是 obj.sub 对象,而对于 obj.sub 来说并没有 name 属性,因此为 undefined;而 var say = obj.say; 则表示将 say 方法的内存地址赋值给全局变量,因此从全局变量 name 中取值。
运用场景
接下来从 this 在函数环境下的不同运用场景来剖析
事件回调函数
var handler = { nickname: 'anonymous', register: function() { console.log(this.nickname); } } $('#registerBtn').on('click', handler.register); // undefined
以上逻辑点击触发后输出的是 undefined,因为函数被当做事件触发的回调函数执行时,this 是指向该触发事件对应的元素,如要 this 仍然以 handler 对象为执行环境,则可使用函数的 bind 方法进行执行环境对象的绑定操作。
$('#registerBtn').on('click', handler.register.bind(handler)); // anonymous
在 react 中经常需要在回调函数中调用 this.state、this.props,按照上面的分析,将当前环境对象 bind 到回调函数中即可。
如果是使用的箭头函数定义回调函数即可无需 bind,因为箭头函数中 this 就是对应定义时所在的对象。
构造函数
要理解 this 在构造函数中的逻辑就要理清楚构造函数在实例化过程中都发生了什么。
function A() { this.name = 'Tom'; this.age = 20; } var a = new A();
使用 new 命令实例化构造函数 A 的过程中会发生以下流程
bind
bind 方法将函数体中的 this 指向新对象并返回一个新函数
function A() { this.nickname = 'Tom'; this.say = function() { console.log(this.nickname); } } var b = { nickname: 'John' }; var a = new A(); var say = a.say; var say1 = a.say.bind(a); var say2 = a.say.bind(b); say(); // undefined say1(); // Tom say2(); // John
call & apply
call 方法是指 Function.prototype.call,因此每个函数都会具备 call 方法,fun.call(thisArg, arg1, arg2, ...),call 方法接收的第一个参数会替换原有的 this 指向的执行环境对象。
function A() { this.name = 'Tom'; this.sayName = function(){ console.log(this.name); }; } function B() { this.name = 'John'; } var a = new A(); a.sayName.call(new B()); // John
而 apply 方法与 call 的区别仅在于 call 接收参数列表而 apply 接收数组参数或者类数组对象(如函数的 arguments 对象)。
总结
由于 javascript 的 Event Loop 原理,决定了执行上下文会不断变化,因此 this 对象诞生于表达当前的执行环境对象。
以上所述是小编给大家介绍的javascript的this关键字的用法详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对码农之家网站的支持!
以上就是本次给大家分享的关于java的全部知识点内容总结,大家还可以在下方相关文章里找到相关文章进一步学习,感谢大家的阅读和支持。
Copyright 2018-2020 www.xz577.com 码农之家
版权投诉 / 书籍推广 / 赞助:520161757@qq.com
详解JavaScript 中的 this是如何工作的
一、问题的由来 学懂 JavaScript 语言,一个标志就是理解下面两种写法,可能有不一样的结果。 var obj = { foo: function () {}};var foo = obj.foo;// 写法一obj.foo()// 写法二foo() 上面代码中,虽然obj.foo和foo指向同一个函数,但是执行结果可能不一样。请看下面的例子。 var obj = { foo: function () { console.log(this.bar) }, bar: 1};var foo = obj.foo;var bar = 2;obj.foo() // 1foo() // 2 这种差异的原因,就在于函数体内部使用了this关键字。很多教科书会告诉你,this指的是函数运行时所在的环境。对于 obj.foo() 来说,foo运行在obj环境,所以this指向obj;对于foo()来说,foo运行在全局环境,所以this指向全局环境。所以,两者的运行结果不一样。 这种解释没错,但是教科书往往不告诉你,为什么会这样?也就是说,函数的运行环境到底是怎么决定的?举例来说,为什么 obj.foo() 就是在obj环境执行,而……
JavaScript中的this陷阱的最全收集并整理(没有之一)
当有人问起你JavaScript有什么特点的时候,你可能立马就想到了单线程、事件驱动、面向对象等一堆词语,但是如果真的让你解释一下这些概念,可能真解释不清楚。有句话这么说:如果你不能向一个6岁小孩解释清楚一个东西,那么你自己也不懂这个东西。这句话或许有点夸张,但是极其有道理。个人觉得,如果需要掌握一门语言,掌握它的API只是学了皮毛,理解这门语言的精髓才是重点。提及JavaScript的精髓,this、闭包、作用域链、函数是当之无愧的。这门语言正式因为这几个东西而变得魅力无穷。 博客的标题是《JavaScript中的this陷阱的最全收集--没有之一》,很显然这篇博客阐述的是this。相信做过JavaScript开发的人都遇到过不少this的陷阱,我自己本身也遇到过不少坑,但是如果非要给出一个系统的总结的话,还没有足够的底蕴。非常幸运的是,今……
JavaScript中this用法学习笔记
JavaScript这门语言中,最令人迷惑的地方有三个,闭包、this、原型。针对大多数人,可以利用词法作用域等避开this的坑,但是我们不能一直生活在舒适区,要敢于打破砂锅问到底,对我们来说也是一种提升。 一、一般对this关键字的误解: 1、this指向函数自身 2、this指向函数词法作用域 我们可以看以下一段代码: function test() {test.a = 1;this.a = 2;console.log(test.a);console.log(this.a);console.log(test.a === this.a);}test();console.dir(test); 在上面这段代码中,我们在全局声明一个方法test,给test中的a属性赋值1,当前方法中的this中的a属性赋值2,加入this指向函数自身,那么test.a === this,a并且都等于2. 下面我们来看下这段代码的运行结果: 从上可以看出,scopes为全局作用域window,this也指向这里,虽然函数本身也是一个对象,但是this并不指向这里。 有一点我们一定要记住,this是……