日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Javascript基础之-原型(prototype)

發(fā)布時(shí)間:2025/3/8 java 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Javascript基础之-原型(prototype) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

首先呢,prototype是對(duì)象里的一個(gè)內(nèi)置屬性,并且呢,這個(gè)屬性是對(duì)于其他對(duì)象的一個(gè)引用。所以呢,思考下面的例子:

var obj = {a: 2 } var myObj = Object.create(obj); console.log(myObj.a); // 2 console.log(myObj === obj); // false console.log(Object.getPrototypeOf(myObj) === obj); // true Object.getPrototypeOf(myObj).a = 4 console.log(obj.a); // 4

這里可以看到,實(shí)際上Object.create()是新建了一個(gè)對(duì)象,并且這個(gè)對(duì)象的prototype是obj的一個(gè)引用,所以呢,如果咱們直接修改prototype里面的值,原對(duì)象也就跟著變了。

很簡單吧,那么如果執(zhí)行如下代碼的話,會(huì)發(fā)生什么呢?

myObj.a = 10;

是不是認(rèn)為,還跟上面那個(gè)一樣的,obj.a也變成10了呢?實(shí)際上不是的,他的運(yùn)行機(jī)制要比咱們想的稍微復(fù)雜一點(diǎn)點(diǎn)。

實(shí)際上要分三種情況來看:

如果在prototype鏈上存在這個(gè)屬性,并且沒有標(biāo)記為只讀,那么就會(huì)在本對(duì)象上新建一個(gè)新的同名屬性。

如果在prototype鏈上存在這個(gè)屬性,并且標(biāo)記為只讀,那么將無法修改已有屬性或在本對(duì)象上新建一個(gè)同名屬性,如果是嚴(yán)格模式的話,還會(huì)報(bào)錯(cuò)。

如果在prototype鏈上只是存在此setter,那么一定會(huì)調(diào)用此setter,并不會(huì)添加屬性到對(duì)象上,更不會(huì)重新定義這個(gè)setter

很枯燥是吧,來看例子,對(duì)照著上面的情況,好好的理解一下:

var obj = {a: 2,set c(num) {console.log('exec it');} } var myObj = Object.create(obj); myObj.a = 10; console.log(obj.a); // 2 console.log(myObj.a); // 10 Object.defineProperty(obj, 'b', {value: 3,writable: false }) myObj.b = 10; console.log(myObj.b); // 3 myObj.c = 20; // "exec it" console.log(myObj.c); // undefined

假如上面的已經(jīng)理解了,那么可以思考下下面的運(yùn)行結(jié)果:

var obj = {a: 2 } var myObj = Object.create(obj); console.log(++myObj.a); // 3 console.log(obj.a); // 2

這個(gè)在咱們實(shí)際的編碼中時(shí)有發(fā)生,看代碼是想把a(bǔ)改成3,但是由于上面第一種情況的影響,實(shí)際上是新建了一個(gè)同名屬性3,并且賦值給了myObj。

上面我們談?wù)摰亩际瞧胀▽?duì)象的prototype的一些特性,接下來,咱們就要講關(guān)于new關(guān)鍵字相關(guān)的一些知識(shí)點(diǎn)了,思考下面的例子

function Foo() {} var a = new Foo(); console.log(Object.getPrototypeOf(a) === Foo.prototype); // true var b = new Foo(); Object.getPrototypeOf(b).saySomething = function () {console.log('say something'); } a.saySomething(); // "say something"

很明顯,在new的過程中呢,生成了一個(gè)新對(duì)象,并且把Foo.prototype引用到了新對(duì)象的prototype。那么因?yàn)槭且?#xff0c;所以通過b改變其原型上的prototype的值,Foo.prototype里也會(huì)跟著改變。

那么new的過程,是不是一定引用的是函數(shù)的prototype呢?也不一定,比如說下面的例子。

function Foo() {return {a: 3} } var a = new Foo(); console.log(Object.getPrototypeOf(a) === Foo.prototype); // false console.log(Object.getPrototypeOf(a) === Object.prototype); // true console.log(a.a); // 3

在這個(gè)例子中,由于new的時(shí)候,返回的是一個(gè)對(duì)象,所以最后實(shí)際上a最終引用的是Foo最后返回的那個(gè)小對(duì)象,所以其prototype就是Object.prototype,而不是Foo.prototype

甚至說,Foo.prototype也是可以被改變的,不過在這時(shí)候,new出來的對(duì)象,其prototype就是被改過的那個(gè)對(duì)象。

var protoObj = {b: 10 } function Foo() {} Foo.prototype = protoObj; var a = new Foo(); console.log(Object.getPrototypeOf(a) === Foo.prototype); // true console.log(Object.getPrototypeOf(a) === protoObj); // true console.log(a.b); // 10

你看,如果prototypeObj修改了默認(rèn)的Foo.prototype,所以最后,實(shí)際上形成了這么一個(gè)引用鏈:a.prototype => foo.prototype => protoObj=>Object.prototype。

所以說結(jié)論吧,在new的時(shí)候,實(shí)際上執(zhí)行會(huì)包含這么幾步,

如果有return并且返回的是一個(gè)對(duì)象的話,則直接返回return后的那個(gè)對(duì)象。

反之,則新建一個(gè)對(duì)象。

并且吧函數(shù)的prototype引用到新建對(duì)象的prototype中。

所以說,原型,可以理解為我本來對(duì)象有一個(gè)prototype,引用著其他的對(duì)象,當(dāng)我這個(gè)對(duì)象的prototype引用了另一個(gè)對(duì)象的prototype,一般情況會(huì)到Object.prototype為止,這樣就組成了一個(gè)原型鏈,原型鏈也就是互相引用的引用鏈。而這個(gè)引用鏈?zhǔn)强梢愿鶕?jù)自己的需求去改。

好了,簡短的一小節(jié)就完事了,如果有不明白的,或者有疏漏的地方,或者有什么地方想和我討論的,可以留言給我哦。

本文轉(zhuǎn)載自http://www.lht.ren/article/8/

總結(jié)

以上是生活随笔為你收集整理的Javascript基础之-原型(prototype)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。