this通常用於指向對象(綁定對象);javascript
01、在普通函數調用中,其內部的this指向全局對象(window);html
function funcName(){
this.name = 'Jack';
console.log(this);// Window
}
funcName();
console.log(window.name);// Jack
console.log(this.name);// Jackjava
上述代碼先聲明一個函數名爲funcName的函數,給函數內部的對象添加屬性name,並打印this的指向(window),分別打印this的屬性值和全局對象(window)的屬性值,兩者相等說明this指向全局對象(window);git
02、在構造函數調用中,其內部的this指向新建立的對象github
function Person() {
this.name = '郭嘉';
console.log(this);// Person {name: "郭嘉"}
}
var p1 = new Person();
console.log(p1.name); // 郭嘉
console.log(window.name);// 空數組
上述代碼先聲明一個函數名爲Person的構造函數,給構造函數內部的對象添加屬性name,並打印this的指向(新建立的對象:Person {name: "郭嘉"}),用Person構造函數實例化一個對象p1,分別打印p1的屬性值和全局對象(window)的屬性值,兩者不相等說明this指向的是新建立的對象(Person {name: "郭嘉"})而不是全局對象(window);app
補充:使用new關鍵字建立構造函數的實例對象的系統內部流程函數
/*用new關鍵字建立構造函數的實例的系統內部流程*/
//001 使用new 關鍵字在內部默認建立一個對象
//002 在構造函數內部,把默認建立的對象賦值給this
//003 經過this來設置對象的屬性和方法
//004 默認把新建立的對象返回給咱們
function Person() {
//var this = new Object();//使用new 關鍵字在內部默認建立一個對象,並在構造函數內部,把默認建立的對象賦值給this
this.name = '郭嘉';//經過this來設置對象的屬性和方法
console.log(this);// Person {name: "郭嘉"}
//return this;// 默認把新建立的對象返回給咱們
}測試
03、在對象的方法調用中,其內部的this指向調用的對象自己this
//以對象的方法來進行調用
var obj = {
name:"張三", // 對象的屬性
getName:function () { // 對象的方法
console.log(this);// Object {name: "張三"}
}
};
obj.getName();// 對象的方法調用
console.log(obj.name); // 張三
console.log(window.name);// 空
上述代碼先聲明一個對象名爲obj的對象,給對象添加屬性name,和方法getName,並在方法內部打印this的指向(對象自己:Object {name: "張三"}),調用對象的方法,打印this的指向是對象自己(Object {name: "張三"})而不是全局對象(window);
04、在事件處理中,其內部的this指向產生這個事件源的對象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button id='btn'>click</button>
<script>
var btn = document.getElementById('btn');// 獲取id爲btn的標籤
btn.onclick = function () {// 按鈕點擊事件
console.log(this);
// <button id='btn'>click</button>
};
</script>
</body>
</html>
上述代碼先用html建立一個按鈕,再給這個按鈕添加一個點擊事件,並打印this的指向(<button id =」btn」>click</button>),得出結論是this指向產生事件源的對象(<button id =」btn」>click</button>);
05、在定時器中其內部的this指針指向window對象
function Person() {
// 備份指針
console.log(this); // Person {}
var self = this;
setInterval(function () {
console.log(self);// Person {}
console.log(this);// Window
}, 20);
}
new Person();
上述代碼先建立一個person函數,再用self來備份一下this指針,再建立定時器,定時器內部的this永遠指針指向window對象,有時候咱們咱們要用到指定的對象不是window對象,咱們能夠經過備份指針來實現;
06、經過call或者apply方式調用中(函數上下文),this指向的是當前的上下文,主要是改變this的指向
call方法: 傳入的參數數量不固定
第一個參數是要綁定給this的值(即函數體內this對象的指向)
第二個參數開始日後,每一個參數都依次的傳入做爲函數的參數
apply: 接收兩個參數
第一個參數是要綁定給this的值(即函數體內this對象的指向)
第二個就是一個參數數組
function Person() {
this.name = 'Jack';
}
function Boy() {
Person.call(this);
console.log(this);// Boy {name: "Jack"}
}
var b1 = new Boy();
上述代碼建立兩個構造函數Person和Boy,使用call方法讓Person構造函數中的this指向Boy構造函數,至關於把Person構造函數內對象的屬性和方法深拷貝一份(包括引用類型:指針和堆空間的數據)
var obj = {
name:"張三",
getName:function (param1,param2) {
console.log(this.name,param1,param2);
}
}
obj.getName("123","456"); //張三 123 456
var obj2 = {name:"李四"};
obj.getName.call(obj2); //打印李四 undefined undefined
obj.getName.call(obj2,"測試字符串01","測試的字符串02"); // 李四 測試字符串01 測試的字符串02
obj.getName.apply(obj2,["123","456"]); // 李四 123 456
上述代碼先建立一個對象obj並添加屬性name和方法getName,調用自身的方法得出的結果(張三 123 456),再建立一個對象obj2,添加屬性name,obj.getName.call(obj2);這句話的意思是obj的方法getName借給obj2使用,其obj方法內部的this指向obj2;得出的結果是李四 undefined(沒有傳參) undefined(沒有傳參);call方法主要是改變this的指向;apply的方法做用和call同樣,只是傳的參數不同,call能夠只傳一個參數(要綁定給this的值),也能夠傳多個;而apply接收兩個參數(要綁定給this的值,[]),第二個參數是數組,數組的長度不定。
This的丟失問題
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="box"></div>
<script>
var box = document.getElementById('box');// 獲取標籤
var getId = document.getElementById;//
var box = getId('box');// Uncaught TypeError: Illegal invocation (未捕獲的類型錯誤)
console.log(box);
</script>
</body>
</html>
上述代碼先在html中建立一個id爲box的div,而後再js中獲取標籤,有時候咱們嫌獲取標籤的方法太長了,想要縮減一下(var getId = document.getElementById),再調用,然而上述代碼調用時則報錯了!緣由是方法內部的this指針丟失了,原先document.getElementById內部實現中用到this指針,其指向document對象,而getId調用時是按普通函數調用的,其內部的this指針指向window對象,因此執行到這一步的時候報錯!
如今用apply方法來修正this的指向
//借用apply來修正this
document.getElementById = (function (func) {
return function () {
return func.apply(document,arguments);
}
})(document.getElementById);
var getId = document.getElementById;
/*上句代碼等同於下面這句代碼
var getId = function () {
return document.getElementById.apply(document,arguments);
}*/
var box = getId('box'); //不會報錯
console.log(box);// <div id="box"></div>
上述代碼先在document.getElementById方法內部添加一個讓this指針一直指向document對象的操做;document.getElementById =(function(func){})(document.getElementById);這是一個當即執行函數,把document.getElementById看成實參傳進去,而函數內部則返回另外一個函數,而這個函數內部則執行改變this指向的操做document.getElementById.apply(document,arguments);意思是讓this永遠指向document對象;arguments指的是傳進去的實參Id(box);
This關鍵字永遠指向實際調用者
this通常用於指向對象(綁定對象);
01、在普通函數調用中,其內部的this指向全局對象(window);
function funcName(){
this.name = 'Jack';
console.log(this);// Window
}
funcName();
console.log(window.name);// Jack
console.log(this.name);// Jack
上述代碼先聲明一個函數名爲funcName的函數,給函數內部的對象添加屬性name,並打印this的指向(window),分別打印this的屬性值和全局對象(window)的屬性值,兩者相等說明this指向全局對象(window);
02、在構造函數調用中,其內部的this指向新建立的對象
function Person() {
this.name = '郭嘉';
console.log(this);// Person {name: "郭嘉"}
}
var p1 = new Person();
console.log(p1.name); // 郭嘉
console.log(window.name);// 空
上述代碼先聲明一個函數名爲Person的構造函數,給構造函數內部的對象添加屬性name,並打印this的指向(新建立的對象:Person {name: "郭嘉"}),用Person構造函數實例化一個對象p1,分別打印p1的屬性值和全局對象(window)的屬性值,兩者不相等說明this指向的是新建立的對象(Person {name: "郭嘉"})而不是全局對象(window);
補充:使用new關鍵字建立構造函數的實例對象的系統內部流程
/*用new關鍵字建立構造函數的實例的系統內部流程*/
//001 使用new 關鍵字在內部默認建立一個對象
//002 在構造函數內部,把默認建立的對象賦值給this
//003 經過this來設置對象的屬性和方法
//004 默認把新建立的對象返回給咱們
function Person() {
//var this = new Object();//使用new 關鍵字在內部默認建立一個對象,並在構造函數內部,把默認建立的對象賦值給this
this.name = '郭嘉';//經過this來設置對象的屬性和方法
console.log(this);// Person {name: "郭嘉"}
//return this;// 默認把新建立的對象返回給咱們
}
03、在對象的方法調用中,其內部的this指向調用的對象自己
//以對象的方法來進行調用
var obj = {
name:"張三", // 對象的屬性
getName:function () { // 對象的方法
console.log(this);// Object {name: "張三"}
}
};
obj.getName();// 對象的方法調用
console.log(obj.name); // 張三
console.log(window.name);// 空
上述代碼先聲明一個對象名爲obj的對象,給對象添加屬性name,和方法getName,並在方法內部打印this的指向(對象自己:Object {name: "張三"}),調用對象的方法,打印this的指向是對象自己(Object {name: "張三"})而不是全局對象(window);
04、在事件處理中,其內部的this指向產生這個事件源的對象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button id='btn'>click</button>
<script>
var btn = document.getElementById('btn');// 獲取id爲btn的標籤
btn.onclick = function () {// 按鈕點擊事件
console.log(this);
// <button id='btn'>click</button>
};
</script>
</body>
</html>
上述代碼先用html建立一個按鈕,再給這個按鈕添加一個點擊事件,並打印this的指向(<button id =」btn」>click</button>),得出結論是this指向產生事件源的對象(<button id =」btn」>click</button>);
05、在定時器中其內部的this指針指向window對象
function Person() {
// 備份指針
console.log(this); // Person {}
var self = this;
setInterval(function () {
console.log(self);// Person {}
console.log(this);// Window
}, 20);
}
new Person();
上述代碼先建立一個person函數,再用self來備份一下this指針,再建立定時器,定時器內部的this永遠指針指向window對象,有時候咱們咱們要用到指定的對象不是window對象,咱們能夠經過備份指針來實現;
06、經過call或者apply方式調用中(函數上下文),this指向的是當前的上下文,主要是改變this的指向
call方法: 傳入的參數數量不固定
第一個參數是要綁定給this的值(即函數體內this對象的指向)
第二個參數開始日後,每一個參數都依次的傳入做爲函數的參數
apply: 接收兩個參數
第一個參數是要綁定給this的值(即函數體內this對象的指向)
第二個就是一個參數數組
function Person() {
this.name = 'Jack';
}
function Boy() {
Person.call(this);
console.log(this);// Boy {name: "Jack"}
}
var b1 = new Boy();
上述代碼建立兩個構造函數Person和Boy,使用call方法讓Person構造函數中的this指向Boy構造函數,至關於把Person構造函數內對象的屬性和方法深拷貝一份(包括引用類型:指針和堆空間的數據)
var obj = {
name:"張三",
getName:function (param1,param2) {
console.log(this.name,param1,param2);
}
}
obj.getName("123","456"); //張三 123 456
var obj2 = {name:"李四"};
obj.getName.call(obj2); //打印李四 undefined undefined
obj.getName.call(obj2,"測試字符串01","測試的字符串02"); // 李四 測試字符串01 測試的字符串02
obj.getName.apply(obj2,["123","456"]); // 李四 123 456
上述代碼先建立一個對象obj並添加屬性name和方法getName,調用自身的方法得出的結果(張三 123 456),再建立一個對象obj2,添加屬性name,obj.getName.call(obj2);這句話的意思是obj的方法getName借給obj2使用,其obj方法內部的this指向obj2;得出的結果是李四 undefined(沒有傳參) undefined(沒有傳參);call方法主要是改變this的指向;apply的方法做用和call同樣,只是傳的參數不同,call能夠只傳一個參數(要綁定給this的值),也能夠傳多個;而apply接收兩個參數(要綁定給this的值,[]),第二個參數是數組,數組的長度不定。
This的丟失問題
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="box"></div>
<script>
var box = document.getElementById('box');// 獲取標籤
var getId = document.getElementById;//
var box = getId('box');// Uncaught TypeError: Illegal invocation (未捕獲的類型錯誤)
console.log(box);
</script>
</body>
</html>
上述代碼先在html中建立一個id爲box的div,而後再js中獲取標籤,有時候咱們嫌獲取標籤的方法太長了,想要縮減一下(var getId = document.getElementById),再調用,然而上述代碼調用時則報錯了!緣由是方法內部的this指針丟失了,原先document.getElementById內部實現中用到this指針,其指向document對象,而getId調用時是按普通函數調用的,其內部的this指針指向window對象,因此執行到這一步的時候報錯!
如今用apply方法來修正this的指向
//借用apply來修正this
document.getElementById = (function (func) {
return function () {
return func.apply(document,arguments);
}
})(document.getElementById);
var getId = document.getElementById;
/*上句代碼等同於下面這句代碼
var getId = function () {
return document.getElementById.apply(document,arguments);
}*/
var box = getId('box'); //不會報錯
console.log(box);// <div id="box"></div>
上述代碼先在document.getElementById方法內部添加一個讓this指針一直指向document對象的操做;document.getElementById =(function(func){})(document.getElementById);這是一個當即執行函數,把document.getElementById看成實參傳進去,而函數內部則返回另外一個函數,而這個函數內部則執行改變this指向的操做document.getElementById.apply(document,arguments);意思是讓this永遠指向document對象;arguments指的是傳進去的實參Id(box);
This關鍵字永遠指向實際調用者
https://github.com/350469960/OS/blob/master/javascript/this.md