面向对象:浅谈this以及this指向问题
-
this 是在函数执行的时候确立的,而不是声明的时候,他的指向完全取决于函数调用的地方(箭头函数除外),当一个函数执行的时候,他会创建一个执行上下文,包括函数在哪里被调用(调用栈)、调用方式、参数等,this 就是一个记录的属性,他会在函数执行的过程中被用到
-
this的指向
-
谁调用指向谁
-
事件监听函数内部,this指向绑定该监听器的那个元素节点
-
构造函数内部,this指向创建的新对象
-
箭头函数,没有自己的arguments、this,所以this使用上层引用环境中的this
-
一个函数没有前缀调用(被引用),也就是普通调用,this指向全局对象,严格模式(use strict)下 this 是 undefined
-
-
函数运行环境
在函数内部,this的值取决于函数被调用的方式
-
简单调用(非严格模式)
function f1 () { console.log(this) } //在浏览器环境 f1 () ; // window //在Node环境 f1 () ; // global
-
严格模式
function f2 () { 'use strict'; console.log(this) } f2 () ; // undefined
-
-
使用call() 或者 apply () 方法,改变 this 的指向
//如果想把this的值从一个环境传到另一个,就可以调用call()或者 apply()方法 var o = { a: 'Cus' }; var o1 = { a:'Cus1' }; var a = 'Global'; function whatThis(arg){ console.log(this.a) } whatThis(); // Global; whatThis.call(o); // Cus; whatThis.apply(o); // Cus; whatThis.call(o1); // Cus1; whatThis.apply(o1); // Cus1;
注意:强行指向 ,即改变函数的调用对象,call() 和 apply() 有什么异同
-
两者方法类似,区别就是接收的参数形式不同
-
apply(thisObj, [argsArray])
-
call(thisObj,arg1,arg2,arg3)
-
apply()接收的是数组,call()接收的是以逗号分隔的参数
-
如果传递给this的值不是一个对象,JavaScript 会尝试使用内部 ToObject 操做将其转换为对象
function bar () { console.log(bobject.prototype.toString.call(thiss)); } // 原始值 7 被隐式转为对象 bar.call(7); // [object Number]
-
-
bind() 方法
ES5 引入 Function.prototype.bind()
调用 f.bind() 方法创建一个与 f 具有相同函数体和作用域的函数
但是在这个函数中,this 将永久性的被绑定到了bind 的第一个参数,无论函数是怎么样调用的
var a3 = 'Global'; function f3() { console.log(this.a3); // zhangsan return this.a3; } var g = f3.bind({a3:"zhangsan"}); console.log(g()); // zhangsan var h = g.bind({a3:'haha'}); // bind()只生效一次,再次修改也不会生效 console.log(h()); // zhangsan var o3 = { a3 : 37, f3: f3, g : g , h : h }; console.log(o3.f3(),o3.g(),o3.h); // 37, "zhangsan", 37 "zhangsan" ƒ () { [native code] }