javascript練習題
-
-
-
- 1.this指向(小試牛刀)
- 2.this指向(難度提升)
- 3.this指向(難度更新)
- 4.this指向:
- 5.this指向
- 6.this指向
-
-
使用 JavaScript 開發的時候,很多人多多少少都會被 this 的指向問題搞蒙圈,但是實際上,關于 this 的指向,記住最核心的一句話:哪個對象調用函數,函數裡面的this指向哪個對象。
接下來我們看看幾個例子:
1.this指向(小試牛刀)
<script type="text/javascript">
function test(a){
this.b = a;
console.log(this);
}
test(3);
console.log(b);//3 這裡相當于與通路window.b
</script>
運作結果:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2YfNWawNyZuBnL3kTNzATN1ADMwIjNwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
1.因為test函數是在整個window對象中,當我們調用test函數時,相當于window.test(3),是以此時的this指向window。
2.因為函數中有this.b,又因為this指向,是以在調用時,給window對象添加了一個b屬性
2.this指向(難度提升)
<script type="text/javascript">
var obj = {
a:1,
c:2,
say:function(a){
console.log("this1: "+this);
var sayA = function(a){
console.log("this2: "+this);
this.a = a;
};
function sayC(){
console.log("this3: "+this);
}
sayA(a);
sayC()
}
}
obj.say(3);
console.log(obj.a+" "+obj.c);
console.log(window.a+" "+window.c);
</script>
運作結果:
是不是跟想的有點不一樣呢?
我們要記住這句話:哪個對象調用函數,函數裡面的this指向哪個對象。
1.當我們使用obj調用say函數時,say作為obj的屬性,this當然會指向obj對象,是以this1指向的是obj對象
2.為什麼sayA中的this指向window呢,因為sayA函數被執行時預設被window調用,是以this指向window,此時還向window中添加了一個a屬性
3.sayC函數也是如此,預設被window調用
3.this指向(難度更新)
<script type="text/javascript">
function Person(name,age){
this.name = name;
this.age = age;
}
var person1 = new Person("張三",18);
var person2 = Person("李四",12);
console.log(person1);
console.log(person2);
console.log(person1.name,person1.age);
console.log(window.name,window.age);
</script>
運作結果:
是不是又懵了?
在這裡補充一下new關鍵字的作用:
a.在構造函數代碼開始執行前,建立一個空的對象
b.修改this的指向,把this指向剛剛建立出來的空對象
c.執行函數的代碼
d.在函數完成之後傳回this–即建立出來的對象
1.此時Person相當于構造函數,使用new關鍵字後,建立一個空對象,并将this指向這個對象,是以列印時person1是一個對象,裡面有name和age屬性
2.為什麼person2是undefined呢?此時的Person(“李四”,12) 相當于函數執行,沒有傳回值,是以person2為undefined。
3.為什麼window中有name和age屬性可以列印?因為Person(“李四”,12)相當于window.Person(“李四”,12),是以Person函數執行時,将name和age屬性添加到window中去了
4.this指向:
<script type="text/javascript">
function Test(a, b) {
this.a = a;
this.b = b;
this.say = function (a, b) {
this.a = a;
this.b = b;
console.log(this);
console.log(a, b);
}
}
var obj1 = new Test(1, 1);
console.log(obj1.a, obj1.b);
obj1.say();
console.log(obj1.a, obj1.b);
var obj2 = { a: 2, b: 2 };
obj1.say(4, 4)
console.log(obj1.a,obj1.b);
console.log("------------");
obj1.say.call(obj2, 3, 3);
console.log(obj2.a + "--" + obj2.b);//3--3
</script>
運作結果:
是不是又又懵逼了??
我們一條一條的分析:
1.首先我們可以知道,obj1是構造函數Test new出來的對象,是以列印屬性a,b時,就是當時傳參進去的值 (1 和 1)
2. obj1.say(); 當obj1.調用say時,因為say是obj1的屬性,是以say的this也指向obj1,調用say函數時,由于沒有傳參,是以say中的a,b都為undefined,因為this指向obj1,是以也将obj1中的a,b屬性進行了修改。
3.call方式可以用來暫時修改this指向,第一個參數傳指定對象,後面的進行傳參,是以此時的this指向obj2,同時将obj2中的a,b屬性值也進行了修改。
連結: JavaScript 中 call()、apply()、bind() 的用法,及差別.
5.this指向
看到這裡也不容易,出兩道簡單的題考考你吧!
<script type="text/javascript">
function test(){
var age = "張三";
console.log(this.age);
console.log(this);
}
test();
</script>
運作結果:
<script type="text/javascript">
var obj = {
name:"張三",
sayName:function(){
console.log(this);
console.log(this.name);
function show(){
console.log(this);
}
show()
}
}
obj.sayName()//
window.obj.sayName();//obj本來就在window中,與上面的結果一樣
</script>
運作結果:
6.this指向
如果一個函數中有this,這個函數中包含多個對象,盡管這個函數是被最外層的對象所調用,this指向的也隻是它上一級的對象
<script type="text/javascript">
var obj = {
name:"小明",
objInner:{
name:"小紅",
sayName:function(){
console.log(this);
console.log(this.name);
}
}
}
obj.objInner.sayName();
</script>
運作結果: