this啊

绑定规则

默认绑定

独立函数调用( 独立函数:不加任何修饰的)
其他规则不适用时

1)非严格模式下定义函数,默认绑定到window

function fun() {
  console.log(this.a);
}
var a = 2;
fun(); //2

2) 严格模式下定义函数,默认绑定到undefined

function fun() {
  "use strict";
  console.log(this.a);
}
var a = 2;
fun(); //TypeError:this is no undefined

特别地,
严格模式下调用函数 ,依然默认绑定到window

function fun() {
  console.log(this.a);
}
var a = 2;
(function () {
  "use strict";
  fun(); //2
})();

隐式绑定

用于:调用位置有上下文对象,被某个对象拥有
当被调用时,foo函数的this会绑定到obj(上下文对象);故this.a和obj.a一样
foo无论是直接在obj中定义,还是先定义再添加为obj引用属性,严格说foo函数不属于obj对象

// foo:function object Oriented面向对象函数
function foo() {
  console.log(this.a);
}
var obj = {
  a: 2,
  foo: foo,
};
obj.foo();//2

对象属性引用链仅最后一层在调用位置中作用

function foo() {
  console.log(this.a);
}
var obj2 = {
  a: 42,
  foo: foo,
};
var obj1 = {
  a: 2,
  obj2: obj2,
};
obj1.obj2.foo(); //42

隐式丢失

例1解析:
bar是obj.foo的一个引用,但实际引用的是foo函数
bar()是独立函数调用,应用了默认绑定

 function foo() {
    console.log(this.a);
  }
  var obj = {
    a: 2,
    foo: foo,
  };
  // 函数别名
  var bar = obj.foo;
  //a是window的属性
  var a = "oops,global";
  bar(); //oops,global

例2:回调函数
参数传递是一种隐式赋值,故传入函数也会被隐式赋值

function foo() {
 console.log(this.a);
}
function doFoo(fn) {
 // fn引用的是foo
 fn();
}
var obj = {
 a: 2,
 foo: foo,
};
var a = "oops,global";
doFoo(obj.foo); //oops,global

显式绑定

对象内部不包含引用的情况下,在对象上强制调用函数
方法:
call()
apply()

function foo() {
  console.log(this.a);
}
var obj = {
  a: 2,
};
foo.call(obj);//2

隐式丢失的解决方法-硬绑定

是一种显式的强制绑定
特点:
1.无论以何种方式调用(独立函数调用、回调函数),都会手动在绑定对象上调用函数
2.不能再修改绑定

function foo() {
	console.log(this.a);
}
var obj = {
	a: 2,
};
//创建bar函数
var bar = function () {
	// 手动调用
	// 将foo的this强制绑定到obj
	foo.call(obj);
};
// 硬绑定后,独立函数调用会手动在obj调用foo
bar(); //2
// 硬绑定后,回调函数仍会手动在obj调用foo
setTimeout(bar, 100); //2
// 硬绑定后,不能再修改绑定
bar.call(window); //2

优化:辅助函数-可重复使用

function foo(something) {
	 console.log(this.a, something);
	 return this.a + something;
}
var obj = {
	 a: 2,
};
// 辅助函数
function bind(fn, obj) {
	 return function () {
	  	 return fn.apply(obj, arguments);
	 };
}
var bar = bind(foo, obj);
var b = bar(3); //2 3
console.log(b); //5

优化:ES5内置方法Function.prototype.bind

function foo(something) {
 console.log(this.a, something);
 return this.a + something;
}
var obj = {
 a: 2,
};
var bar = foo.bind(obj);
var b = bar(3); //2 3
console.log(b); //5

隐式丢失的解决方法-API调用的‘上下文’

指第三方库的函数、JavaScript和宿主环境中的内置函数,提供可选参数context上下文
本质通过call()\apply()实现了显示绑定
例如:forEach

function foo(el) {
	console.log(el, this.id);
}
var obj = {
	id: "awesome",
};
[1, 2, 3].forEach(foo, obj); 
//1 'awesome' 2 'awesome' 3 'awesome

new绑定

事实上,不存在构造函数;只有对函数的’构造调用’

function foo(a) {
  this.a = a;
}
var bar = new foo(2);
console.log(bar.a); //2

优先级

new绑定——显式绑定——隐式绑定——默认绑定

具体规则

规则上下文
对象.方法()对象
函数()window
数组[下标]()数组
IIFEwindow
定时器window
DOM事件处理函数绑定DOM的元素
call和apply任意指定

规则1-对象.方法()-对象

例1

function fn(){
	console.log(this.a+this.b);//99
}
var obj={
	a:66,
	b:33,
	fn:fn
};
obj.fn();

例2

var obj1={
a:1,b:2,fn:function(){
console.log(this.a+this.b);//7
}
};
var obj2={
a:3,
b:4,
fn:obj1.fn
};
obj2.fn();

例3

function outer() {
     var a = 11;
     var b = 22;
     return {
         a: 33, b: 44, fn: function () {
             console.log(this.a + this.b);//77
         }
     };
}
outer().fn();

例4

function fun() {
      console.log(this.a + this.b);//7
}
var obj = {
      a: 1, 
      b: 2, 
      c: [{
          a: 3, b: 4, c: fun
      }]
};
var a = 5;
obj.c[0].c();
//obj.c[0]对应对象[{a: 3, b: 4, c: fun}]

规则2-函数()-window

例1:方法赋值给全局变量fn,全局调用fn

var obj1={
	a:1,
	b:2,
	fn:function(){
	console.log(this.a+this.b);//7
	}
};
var a=3;
var b=4;
var fn=obj1.fn;
fn();

例2:第一层-obj.fun(),this指代obj;第二层-fun(),this指代window

function fun(){
	return this.a+this.b;
}
var a=1;
var b=2;
var obj={
	a:3,
	b:fun(),
	fun:fun
};
var result=obj.fun();
console.log(result);//6

规则3-数组[下标]()-数组

例1

var arr=['A','B','C', function(){
	console.log(this[0]);//'A'
	}
]; 
arr[3]();

例2

function fun(){
	arguments[3]();
}
fun('A','B','C',function(){
	console.1og(this[1]);//B
	}
);

规则4-IIFE-window

var a=1;
var obj={
	a:2,
	fun:(function(){
		var a=this.a;//this-window;this.a-1
		return function(){
			console.log(a+this.a);//this-obj;this.a-2;输出3
		}
	})()
};
obj.fun();

规则5-定时器、延时器-window

◆规则5:定时器、延时器调用函数,上下文是window对象
setInterval(函数,时间);
setTimeout(函数,时间);
规则5题目举例
var obj={
a:1,b:2,fun:function(){
console.log(this.a+this.b);
}}
vara=3;varb=4;
setTimeout(obj.fun,2000);适用规则5
输出7
var obj={
a:1,b:2,fun:function(){
console.log(this.a+this.b);
}}
vara=3;varb=4;
setTimeout(function(){
obj.fun();//适用规则1
},2000);
输出3

规则6-DOM绑定事件-绑定事件的DOM元素

DOM元素.onclick=function(){
};

案例1:请实现效果:点击哪个盒子,哪个盒子就变红,要求使用同一个事件处理函数实现
案例2:请实现效果:点击哪个盒子,哪个盒子在2000ms就变红,要求使用同一个事件处理函数实现

规则7-call&apply-任意指定

两者区别:
call逗号罗列参数;apply数组罗列参数

function sum(b1,b2){
alert(this.c+this.m+this.e+b1+b2);
}
sum.cal1(xiaoming,53);
sum.apply(xiaoming,[53]);

argument作为参数,用apply

function fun1(){
	fun2.apply(this,arguments);
}
function fun2(a,b){
	alert(a+b);//77
}
fun1(3344);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值