阮一峯JavaScript教程:面向對象編程javascript
阮一峯JavaScript教程:實例對象與 new 命令html
也能夠看看這篇文章周大俠啊 進擊的 JavaScript(六) 之 this先了解一下`this的四種綁定規則和箭頭函數的this綁定git
這兩篇文章寫的很好
周大俠啊 進擊的 JavaScript(六) 之 thisgithub
蘇雲的博客編程
下面的this分別是什麼?這幾個函數都是回調函數,回調函數this比較特殊,一般是事件原對象segmentfault
//1. button1.onclick = function () { console.log(this) } //2. button2.addEventListener("click", function () { console.log(this) }) //3.jQuery中 $("ul").on("click", "li", function () { console.log(this) })
this是函數.call()
的第一個參數.app
那麼在直接調用函數的時候(隱式綁定,沒用call),如何知道call()
的第一個參數?
源碼看不到,那就看文檔.框架
看文檔!:
onclick:
addEventListener:
jQuery中:
函數
因此上面三個的this分別是
btutton1元素,button2元素,li元素
$("ul").on("click", "li"/*selector*/, function () { console.log(this)//表明與selector相匹配的元素(li元素) })
this
是call()
的第一個參數,只有寫onclick
,寫addEventListener
和寫jQuery
中on
的人想call()哪一個東西,就把這個this
綁定到哪裏去了,因此要肯定this
,就要看源碼或者文檔!
例如:
button1.onclick = function () { console.log(this) } button1.onclick.call({name:"mataotao"})
能夠直接觸發onclick事件,傳入{name:"mataotao"}
,那麼this
就是{name:"mataotao"}
這個對象
如下來自蘇雲的博客()
6.回調函數的
this
回調函數也只不過是函數的一種,實際上這種狀況已經包含在了前面提到的狀況中。可是因爲回調函數的調用者每每不是咱們本身,而是回調函數的接收者,即某個庫或框架、甚至是JS運行時環境。這樣一來,回調函數在中的this
是什麼就與對方的調用方式有關了,所以變得比較複雜,因此單獨拿出來討論一下。狀況1:沒有明確做用對象的狀況下,一般
this
爲全局對象例如
setTimeout
函數的回調函數,它的this
就是全局對象。你若是但願本身指定this
,能夠經過bind
函數等方法。狀況2:某個事件的監聽器回調函數,一般this就是事件源對象
例如:
button.addEventListener('click', fn)
fn
的中的this
就是事件源button
對象。狀況3:某些API會專門提供一個參數,用來指定回調函數中的
this
例如,咱們能夠從新設計一個能夠指定
this
的setTimeout
:function setTimeoutExt(cb, period, thisArg) { setTimeout(function() { cb.call(thisArg); }, period); }另外,在ExtJS中也大量使用了能夠指定this的接口。
答案:
調用B處的console.log().結果是options
window(console.log()中console是全局window對象裏的一個方法)
我終於明白了原型鏈:
仔細看下面這篇文章,就能明白原型鏈的構造問題:
JavaScript 世界萬物誕生記
我的理解:
原型鏈要分爲兩個部分,原型和鏈,原型就是一個實例對象,可是是最基礎的實例對象.這個實例對象能夠做爲模板/類,讓其餘對象去複製他,複製以後不僅僅有這個原型的屬性,也能夠有本身的屬性.新實現的實例對象.__proto__
指向原來的模板實例對象.
而造出來的對象也能夠當作模板,再由新的機器去以他爲模板造新對象.由此造成了一條__proto__
組成的鏈.
全部的對象都有__proto__
屬性,他們就像被鏈子鏈接在了一塊兒,因此就稱之爲原型鏈
而複製的過程由一個機器來完成.這個機器(好比能夠說是Object())的使用方法就是:按照模板實例對象new()一個新對象,新對象被原來的模板對象用__proto__
鏈子拴着,新對象能夠有本身的新添加的東西.
這個按照模板造新對象的機器.prototype
指向原來的模板實例對象.prototype
就是原來的模板實例對象拴住複製本身機器的鏈子.
寫成代碼就是:
var obj = new Object({ flag: 10 });
就像前面所說,機器用來製造某一類對象。正因如此,機器能夠做爲這類對象的標誌,即面嚮對象語言中 類(class)的概念。因此機器又被稱爲 構造函數。在ES6引入 class關鍵字以前,咱們經常把構造函數叫作類。說明2:用戶自定義的函數一般既能夠做爲普通函數使用,又能夠做爲構造函數來製造對象。ES6新增的class語法定義的函數只能做爲構造函數,ES6新增的=>語法定義的箭頭函數只能做爲普通函數。
.
__proto__
與prototype
的區別__proto__
是全部對象(包括函數對象)都有的一個屬性(固然只是邏輯上有這麼個概念),當咱們說「原型鏈」的時候,就是指 對象經過這個屬性互相鏈接而造成的鏈狀結構。 原型鏈也就是 繼承鏈。
prototype
是隻有函數(準確地說是 構造函數)纔有的一個屬性,例如對於對於某個函數Fun。它的意義在於,當你用var obj = new
Fun() 獲得一個對象obj時,這個obj的原型就是F.prototype。即(new Fun()).__proto__ ===Fun.prototype
,見文中第4個圖。No. 1其實就是
Object.prototype
,No.
2其實就是Function.prototype。我只是爲了強調這兩個對象的重要性,故意這樣說的。不太嚴格地說,前者就是一個空對象相似:{}
,後者就是一個空函數,相似:fubction() {} 。
文中:
**No. 1:Object.prototype
No. 2:Function.prototype**
還有這幾篇文章也不錯:
「每日一題」什麼是 JS 原型鏈? - 方應杭的文章 - 知
看看這篇文章很清楚:
JS 的 new 究竟是幹什麼的? - 方應杭的文章 - 知乎
以共有屬性對象爲模板new出來的新對象的__proto__指向共有屬性對象(我把這個對象叫作模板對象,也叫做原型).這樣共有屬性在內存中只須要存一次!
好比:當咱們造士兵的時候,士兵有共有屬性,有自有屬性,那麼咱們能夠把共有屬性放在一個地方,避免每一次建立士兵都把共有屬性從新建立一次,浪費內存:
既然這樣,那麼咱們能夠把製造士兵的過程寫成一個函數.
而後調用便可
直接使用函數就能夠製造一個有特殊的id,可是__proto__
指向原型士兵的新士兵
那麼可不能夠直接把這個原型對象放到函數裏,組成一個總體?不行,這樣每次調用這個函數,都會在內存中建立這個臨時對象,那麼和原先的不用原型同樣了
解決方法是,把這個原型變爲函數的一個屬性
這種方法省內存且好用.
new()就是剛剛的全部過程
灰色的代碼就是new()作的封裝,不須要你作的事情
共有屬性被new()統一叫作prototype
new其實就是語法糖!
注意:.prototype
對象最開始就是一個擁有constructor
屬性的對象,若是想修改共有屬性,兩種方法:
第一步寫私有屬性,第二步寫共有屬性.
能夠看到這個對象的
1自有屬性,
2__proto__指向的原型對象含有共有屬性.
3constructor指向的構造函數
也能夠看看這篇文章周大俠啊 進擊的 JavaScript(六) 之 this
裏面有new的實現.new與this
下面是節選:
5、new 綁定 若是 使用
new
來建立對象,由於
後面跟着的是構造函數,因此稱它爲構造器調用。對於this
綁定來講,稱爲new
綁定。想知道 構造器調用 中
this
的綁定,就要知道new
到底作了啥了。先來個
new
的實現。看不懂沒關係,在後面原型鏈那篇,還會說的。function New(proto){ //proto 爲傳進來的構造函數 var obj = {}; obj.__proto__ = proto.prototype; proto.apply(obj, Array.prototype.slice.call(argument,1)); //你這要看懂這步就行。這裏把構造函數裏的 this 綁定到了 新的obj 對象上,最後 返回了該新對象,做爲實例對象。 return obj; }因此在使用
new
來建立實例對象時,new
內部把 構造函數的this
綁定到 返回的新對象 上了。function Person(name){ this.name = name; } var c = new Person("zdx"); c.name;
JavaScript 世界萬物誕生記中也提到了new的使用,new的過程就是生產機器按照模板原型對象造出來的新對象的過程!