-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy paththis指向.html
176 lines (146 loc) · 4.14 KB
/
this指向.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>this指向</title>
<link rel="stylesheet" href="">
</head>
<body>
<script>
/*
this执行时才能确定
1、默认绑定(严格/非严格模式)
2、隐式绑定
3、显式绑定(call/apply)
4、new绑定
5、箭头函数绑定
*/
// 默认绑定
var a = 'liben';
function moren1() {
console.log(this.a) // 打印liben this指向全局window
}
moren1()
function moren2() {
"use strict"
console.log(this.a) // 报错 this指向了undefined
}
// moren2()
function moren3() {
console.log(this.a) // 打印liben 严格模式下调用函数则不影响默认绑定
}
(function(){
"use strict"
moren3()
})()
console.log("--------------")
// 隐式绑定
var ysObj = {
b: "liben",
yinshi1: function() {
console.log(this.b)
}
}
ysObj.yinshi1() // 打印liben
var yinshi2 = ysObj.yinshi1 // 函数别名
yinshi2() // undefined 丢失this绑定
function doYinshi(fn) {
fn()
}
doYinshi(ysObj.yinshi1) // undefined 参数传递就是一种隐式赋值 丢失this绑定
setTimeout(ysObj.yinshi1, 1000) // undefined
doYinshi.call(ysObj, ysObj.yinshi1) // undefined
console.log("--------------")
// 显示绑定
function xianshi() {
console.log(this.c)
}
var xsObj = {
c: "xianshi"
}
var xsObj2 = {
c: "xianshi2"
}
xianshi.call(xsObj) // xianshi
xianshi.apply(xsObj) // xianshi
xianshi.bind(xsObj)() // xianshi
xianshi.bind(xsObj2).bind(xsObj)() // xianshi2 bind多次this只绑定第一次
xianshi.bind(xsObj2).call(xsObj) // xianshi2 bind后this指向就不会变了
// 如果我们将null或者是undefined作为this的绑定对象传入call、apply或者是bind,这些值在调用时会被忽略,实际应用的是默认绑定规则
var c = "moren"
xianshi.call(null) // moren
console.log("--------------")
// new绑定
function New_(d) {
this.d = d
}
var dd = new New_("newnewnew")
console.log(dd.d) // newnewnew
console.log("--------------")
// 箭头函数 箭头函数没有自己的this,箭头函数中的this继承于外层代码块中的this
var jtObj = {
f: "jiantou",
jiantou: () => {
console.log(this.f)
},
putong: function() {
console.log(this.f)
}
}
var f = "123"
jtObj.jiantou() // 123
jtObj.putong() // jiantou
/*
绑定优先级?
箭头函数 > new绑定 > 显式绑定 > 隐式绑定 > 默认绑定
函数是否在new中调用(new绑定),如果是,那么this绑定的是新创建的对象
函数是否通过call,apply调用,或者使用了bind(即硬绑定),如果是,那么this绑定的就是指定的对象
函数是否在某个上下文对象中调用(隐式绑定),如果是的话,this绑定的是那个上下文对象。一般是obj.foo()
如果以上都不是,那么使用默认绑定。如果在严格模式下,则绑定到undefined,否则绑定到全局对象
如果把null或者undefined作为this的绑定对象传入call、apply或者bind,这些值在调用时会被忽略,实际应用的是默认绑定规则
如果是箭头函数,箭头函数的this继承的是外层代码块的this
*/
function _newBind(h) {
this.h = h
console.log(this, this.__proto__ === _newBind.prototype)
}
var newbindObj = {
h: 'h_obj'
}
var NewBind = _newBind.bind(newbindObj)
new NewBind("liben")
console.log("-----------考题---------")
// 考题
var number = 5;
var obj = {
number: 3,
fn1: (function () {
// debugger
var number;
this.number *= 2;
number = number * 2;
number = 3;
return function () {
var num = this.number;
this.number *= 2;
console.log(num);
number *= 3;
console.log(number);
}
})()
}
var fn1 = obj.fn1;
fn1.call(null);
obj.fn1();
console.log(window.number);
function func(num) {
this.count++
}
func.count = 0
func(1)
console.log(func)
console.log(func.count)
</script>
</body>
</html>