導航:首頁 > 編程語言 > js刪除原型鏈中的屬性

js刪除原型鏈中的屬性

發布時間:2021-12-09 08:47:43

1. js for in會輸出對象原型鏈中的屬性嗎

會的,但是可以用 obj.hasOwnProperty(i)來進行判斷篩選

2. js原型鏈中的函數為什麼可以用for in來遍歷

1.原型鏈:

2 for..in

3.例子

functionA(){	this.a="a"	}

functionB(){ this.b="b" }

B.prototype=newA();

vara=newB();

for(varkina){ console.log("屬性"+k+":值"+a[k]) }

4.控制台


3. 深入分析JS原型鏈以及為什麼不能在原型鏈上使

在剛剛接觸JS原型鏈的時候都會接觸到一個熟悉的名詞:prototype;如果你曾經深入過prototype,你會接觸到另一個名詞:__proto__(注意:兩邊各有兩條下劃線,不是一條)。以下將會圍繞prototype和__proto__這兩個名詞解釋為什麼不能在原型鏈上使用對象以及JS原型鏈的深層原理。
一、為什麼不能在原型鏈上使用對象:
先舉一個非常簡單的例子,我有一個類叫Humans(人類),然後我有一個對象叫Tom(一個人)和另一個對象叫Merry(另一個人),很明顯Tom和Merry都是由Humans這一個類實例化之後得到的,然後可以把這個例子寫成如下代碼
function Humans() { this.foot = 2;
}Humans.prototype.ability = true;

var Tom = new Humans();var Merry = new Humans();alert(Tom.foot);//結果:2alert(Tom.ability);//結果:truealert(Merry.foot);//結果:2alert(Merry.ability);//結果:true
以上是一個非常簡單的面向對象的例子,相信都能看懂,如果嘗試修改Tom的屬性ability,則
function Humans() { this.foot = 2;}
Humans.prototype.ability = true;

var Tom = new Humans();var Merry = new Humans();Tom.ability = false;alert(Tom.foot);//結果:2alert(Tom.ability);//結果:falsealert(Merry.foot);//結果:2alert(Merry.ability);//結果:true
以上可以看出Tom的ability屬性的值改變了,但並不影響Merry的ability屬性的值,這正是我們想要的結果,也是面向對象的好處,由同一個類實例化得到的各個對象之間是互不幹擾的;OK,接下來給ability換成object對象又如何?代碼如下:
function Humans() { this.foot = 2;
}Humans.prototype.ability = {
run : '100米/10秒',
jump : '3米'
};var Tom = new Humans();var Merry = new Humans();Tom.ability = {
run : '50米/10秒',
jump : '2米'
};
alert(Tom.ability.run); //結果:'50米/10秒'
alert(Tom.ability.jump); //結果:'2米'
alert(Merry.ability.run); //結果:'100米/10秒'
alert(Merry.ability.jump); //結果:'3米'
以上代碼就是在原型鏈上使用了對象,但從以上代碼可以看出Tom的ability屬性的改變依然絲毫不會影響Merry的ability的屬性,於是乎你會覺得這樣的做法並無不妥,為什麼說不能在原型鏈上使用對象?接下來的代碼就會顯得很不一樣,並且可以完全表達出原型鏈上使用對象的危險性:
function Humans() { this.foot = 2;
}
Humans.prototype.ability = {
run : '100米/10秒',
jump : '3米'};var Tom = new Humans();var Merry = new Humans();Tom.ability.run = '50米/10秒';
Tom.ability.jump = '2米';alert(Tom.ability.run); //結果:'50米/10秒'
alert(Tom.ability.jump); //結果:'2米'
alert(Merry.ability.run); //結果:'50米/10秒'
alert(Merry.ability.jump); //結果:'2米'
沒錯,從以上代碼的輸出結果可以看出Tom的ability屬性的改變影響到Merry的ability屬性了,於是就可以明白在原型鏈上使用對象是非常危險的,很容易會打破實例化對象之間的相互獨立性,這就是為什麼不能在原型鏈上使用對象的原因?是的,但我想說的可不只如此,而是其中的原理,看完後面JS原型鏈的深層原理之後,相信你會完全明白。
在以下第二部份解釋JS原型鏈的深層原理之前,先來明確一個概念:原型鏈上的屬性或方法都是被實例化對象共用的,正因如此,上面的Tom.ability.run='50米/10秒',改動了原型連上的ability才導致另一個對象Merry受影響,既然如此,你可能會問Tom.ability = {......}不也是改動了原型鏈上的ability嗎,為什麼Merry沒有受影響?答案是Tom.ability = {......}並沒有改動原型鏈上的ability屬性,而是為Tom添加了一個自有屬性ability,以後訪問Tom.ability的時候不再需要訪問原型鏈上的ability,而是訪問其自有屬性ability,這是就近原則;OK,如果你仍有疑問,可以用紙筆記下你的疑問,繼續往下看你會更加明白。
二、JS原型鏈的深層原理:
首先要引入一個名詞__proto__,__proto__是什麼?在我的理解里,__proto__才是真正的原型鏈,prototype只是一個殼。如果你使用的是chrome瀏覽器,那麼你可以嘗試使用alert(Tom.__proto__.ability.run),你發現這樣的寫法完全可行,而且事實上當只有原型鏈上存在ability屬性的時候,Tom.ability其實是指向Tom.__proto__.ability的;當然,如果你跑到IE瀏覽器里嘗試必然會報錯,事實上IE瀏覽器禁止了對__proto__的訪問,而chrome則是允許的,當然實際開發中,我並不建議直接就使用__proto__這一屬性,但它往往在我們調試代碼時發揮著重要作用。有人可能會問到底Tom.__proto__和Humans.prototype是什麼關系,為了理清兩者的關系,下面先列出三條法則:
1、對象是擁有__proto__屬性的,但沒有prototype;例如:有Tom.__proto__,但沒有Tom.prototype。
2、類沒有__proto__屬性,但有prototype;例如:沒有Humans.__proto__,但有Humans.prototype(這里必須糾正一下,同時非常感謝『川川哥哥』提出這一處錯處,確實是我在寫到這一點的時候沒有考慮清楚,事實上Humans也是Function的一個實例對象,因此Humans.__proto__===Function.prototype是絕對成立的,稍有特殊的是這時Function.prototype是指向一個Empty(空)函數,值得推敲)。
3、由同一個類實例化(new)得到的對象的__proto__是引用該類的prototype的(也就是我們說的引用傳遞);例如Tom和Merry的__proto__都引用自Humans的prototype。
OK,上面說過Tom.ability={......}其實並沒有改變原型鏈上的ability屬性,或者說並沒有改變Tom.__proto__.ability,而是為Tom添加了一個自有的ability屬性,為了說明這一點,我們再次回到以上的第三個代碼塊,其代碼如下:
function Humans() { this.foot = 2;
}
Humans.prototype.ability = {
run : '100米/10秒',
jump : '3米'};var Tom = new Humans();var Merry = new Humans();Tom.ability = {
run : '50米/10秒',
jump : '2米'};alert(Tom.ability.run); //結果:'50米/10秒'alert(Tom.ability.jump); //結果:'2米'alert(Merry.ability.run); //結果:'100米/10秒'alert(Merry.ability.jump); //結果:'3米'
當為Tom.ability賦予新的值後,再次訪問Tom.ability時就不再指向Tom.__proto__.ability了,因為這時其實是為Tom添加了自有屬性ability,可以就近取值了,你可以嘗試用Chrome瀏覽器分別alert(Tom.ability.run)和alert(Tom.__proto__.ability.run),你會發現確實存在兩個不同的值

4. JS 原型鏈繼承和類繼承各有什麼優缺點

類式繼承就像java的繼承一樣,思想也比較簡單:在子類型構造函數的內部調用超類型內構造函數。

原型式繼容承是藉助已有的對象創建新的對象,將子類的原型指向父類,就相當於加入了父類這條原型鏈

而你的 下面這段代碼不是嚴格意義上的類式繼承,按照Nicholas C.Zakas的說法,這個應該叫做組合式繼承。它調用了兩次parent2()。第一次是 child2.prototype=new parent2('param'); child2就會得到兩個屬性param,getParam(),他們都是parent2的屬性,但是他們在child2的原型中。第二次是parent2.call(this,cparam); 這次又在新對象上創建了實例屬性param,getParam()。於是,這兩個屬性就屏蔽了原型中的兩個同名屬性。這有什麼好處呢,就是你在構建一個child3時也繼承parent2()的屬性,還可以定義自己的屬性。與此同時他長的就和他兄弟不同了,但又有一樣的「血統(使用父類的方法)」。

純手打,歡迎繼續討論

5. 如何判斷屬性是來自自身對象還是js原型鏈最上層對象

varobj={name:'h5course-com'};
obj.hasOwnProperty('name');//true
obj.hasOwnProperty('toString');//false

原型鏈上繼承過來的屬性無法通過hasOwnProperty檢測到,返回false。

注意

雖然in能檢測到原型鏈的屬性,但是回for in卻不行。

資料答參考:

HTML5學堂

6. 什麼是JS的原型屬性,什麼是自身屬性

簡單點說原型屬性就是別人的屬性,而通過原型創建的實例可以創建屬於自己的屬性,因為原型鏈的關系實例不僅可以訪問自身屬性,也能訪問原型屬性,而原型只能訪問到原型屬性,看代碼吧

functionPerson(){
}//聲明Person對象
Person.prototype.name='xiaoMing';//在Person原型上添加name屬性,屬性值為'xiaoMing'

varperson1=newPerson();//創建實例person1
person1.age=18;//在person1上添加屬性age,也就是你說的自身屬性
person1.name='John';//在person1上添加屬性name,這個也算,在實例上添加與原型同名的屬性則會覆蓋掉原型上的同名屬性

//最簡單的使用hasOwnProperty()方法判斷屬性是一個實例屬性(自身屬性)還是原型屬性
alert(person1.hasOwnProperty('age'));//true
alert(Person.hasOwnProperty('age'));//false

//使用delete操作符可以完全刪除自身屬性
alert(person1.name);//John
deleteperson1.name;
alert(person1.name);//xiaoMing

7. js中什麼是原型對象和原型鏈

每個 JavaScript 對象內部都有一個指向其它對象的「指針」或者 「引用「, 並通過這種方式在對象之專間建立了一屬種聯系,形成了一種鏈式結構,我的理解這就是所謂的原型鏈。

functionF(){}//F是一個函數,函數也是對象,而且每個函數都有一個屬性叫:"prototype"
varo=newF();//F.prototype就是o的原型對象

console.log(o.name);
//輸出:undefined

F.prototype.name="foo";
console.log(o.name);
//輸出:foo


//上面這個例子是想說明:通過new在對象o與對象F.prototype之間建立了聯系,這個建立聯系
//的方式有人叫"原型繼承"。當訪問的對象屬性不存在時,就會沿著原型鏈去查找。

8. JavaScript原型,原型鏈 有什麼特點

1.1 一切皆為對象
JavaScript里所有的東西都是對象. 對象是屬性的集合. 數字, 字元串, 布爾值等原始值是"偽對象", 它們同樣擁有屬性, 但是是在棧上分配並按值傳遞. 而其他的對象是堆上分配並按引用傳遞.
一個很重要的概念是,函數也是對象, 能夠作為變數的值, 返回值, 參數或者屬性的值. 函數對象特殊的地方是能通過"xxx()"語法執行包含在xxx函數對象內的代碼. 因為這一特殊性, typeof xxx 將會返回function, 但這只是一種便利設施.

1.2 對象的屬性可以動態添加和刪除

varfoo=newObject();
//為foo對象添加bar屬性
foo.bar="foobar";
alert(foo.bar);//foobar
//刪除foo對象的bar屬性
deletefoo.bar;
alert(foo.bar);//undefined


1.3 除了宿主對象, 其它對象皆由構造函數創建
要有對象, 就先要有創建對象的方法.
在C++/Java等語言, 這個方法就是實例化XXX類的一個實例xxx.
而在JavaScript的世界裡實際沒有類的東西, 當然仍然可以用"類"和"實例"等慣用語來描述JavaScript中類似的行為, 但其機制是完全不同的. JavaScript的對象是由構造函數創建的, 每個對象都有constructor屬性表示創建該對象的構造函數:

functionTest(){this.a="hello";}
vartest=newTest();//由Test構造函數創建
alert(test.constructor);

varo={a:"hello"};
//實際相當於
varo_=newObject();
o_.a="hello";//由Object構造函數創建
alert(o.constructor);

構造函數也是對象, 那構造函數是由什麼創建? 內建的Function函數:

functionTest(a, b)
{
alert(a+b);
}
//相當於:
Test=newFunction(["a","b"],"alert(a+b);");

Function函數又是由什麼創建? 實際上Function是本機代碼實現的固有對象. 不過為了一致性, Function也有constructor屬性, 該屬性指向它自己. 接上面的代碼:

/*輸出functionFunction(){
[nativecode]
}
*/
alert(Test.constructor);

alert(Test.constructor.constructor===Test.constructor);//true
alert(Test.constructor===Object.constructor);//true


2 原型prototype
2.1 prototype的概念
prototype是構造函數的一個屬性, 該屬性指向一個對象. 而這個對象將作為該構造函數所創建的所有實例的基引用(base reference),可以把對象的基引用想像成一個自動創建的隱藏屬性. 當訪問對象的一個屬性時, 首先查找對象本身, 找到則返回; 若不, 則查找基引用指向的對象的屬性(如果還找不到實際上還會沿著原型鏈向上查找, 直至到根).只要沒有被覆蓋的話, 對象原型的屬性就能在所有的實例中找到.
原型默認為Object的新實例, 由於仍是對象, 故可以給該對象添加新的屬性:

//prototype默認為newObject();為了方便, 記為p_obj
functionPerson(name){
this.name=name;
}

//為p_obj增加sayName屬性
Person.prototype.sayName=function(){
alert(this.name);
}

varjohn=newPerson("John");//john的basereference指向p_obj
vareric=newPerson("Eric");//eric的basereference也是指向p_obj

//注意sayName代碼中的this將指向實例化後的對象(this綁定)
john.sayName();//john對象本身沒有sayName屬性,於是訪問原型對象p_obj的sayName屬性
eric.sayName();//訪問同一個原型對象p_obj的sayName屬性


vartmp=Person.prototype;
tmp.boss="David";
//於這個運行點,p_obj已經被修改
//根據上述屬性訪問流程,新的修改(boss屬性)能反映到所有的實例,包括已經創建和即將創建的
alert("John'sbossis"+john.boss);
alert("Eric'sbossis"+eric.boss);


//hisCar和sayCar屬性將增加到john對象而不是p_obj對象..
john.hisCar="Audi";
john.sayCar=function(){
alert(this.name+"hasacarof"+this.hisCar);
}
john.sayCar();
//..因此下一句將錯誤,因為eric對象本身和原型p_obj都沒有sayName屬性
/*eric.sayCar();*/


2.2 原型鏈
除了能修改prototype指向的對象, 還能修改prototype指向哪一個對象, 即為prototype賦予一個不同的對象. 這可以實現一種簡單的繼承:

functionSuperman(){}
Superman.prototype.sayHello=function(){
alert("I'masuperman.");
}

functionSupermanCan(skill){
this.skill=skill;
}
//為prototype賦予Superman的實例..
SupermanCan.prototype=newSuperman();
//..再動態添加新的屬性
SupermanCan.prototype.sayMore=function(){
this.sayHello();//調用"父類"的方法
alert("Ican"+this.skill);
}

vardavid=newSupermanCan("fly");
//output:I'masuperman.Icanfly
david.sayMore();

如果先實例化出一個對象, 再為構造函數prototype賦予一個不同的對象, 將會: 已經創建的對象的基引用不變, 將來創建的對象的基引用為新的原型對象:

varf1={echo:function(){alert("sound");}};
functionFoo(){};
varfoo=newFoo();//foo的基引用指向Object實例
Foo.prototype=f1;
/*未定義,因為這是"foo對象自己或者基引用指向的對象有echo屬性嗎?"
而不是"foo對象自己或者Foo.prototype指向的對象有echo屬性嗎?"*/
alert(foo.echo);

varfoo2=newFoo();//foo2的基引用指f1對象
foo2.echo();//output:sound

所有的構造函數的prototype都不能為空, 就是說Superman.prototype = null 會被解釋引擎無視; 另一方面, Object構造函數也有prototype屬性(該屬性是只讀的, 可以為原型增加屬性,但不能賦予不同的對象), 故因此可以有多層的原型鏈, 但原型鏈的根必定會是Object.prototype . 這意味著給Object.prototype增加屬性影響到所有對象:

Object.prototype.echo=function(){
alert("hello");
}

//echo屬性將增加到所有對象固有對象和自定義對象

vararr=newArray();
arr.echo();
Array.echo();

functionObjCons(){
this.mmy="d";
}
varobj=newObjCons();
obj.echo();
ObjCons.echo();


3. 構造函數和new的實質
構造函數是一個地地道道的函數, 一個函數之所以能成為構造函數, 是因為new運算符:

this.msg="window";

functionTest()
{
alert(this.msg);
}

Test();//window
vartest=newTest();//undefined.因為test對象沒有定義msg屬性

二者區別在於如何切入對象: Test() 在某個對象(例子中為window)的上下文上執行代碼, 即this指向這個對象; new Test()創建一個新對象, 並以這個新的對象為上下文(this指向新對象)執行代碼, 然後返回這個新對象.
假如有個函數:

functionTest(){
varmmy="havemoney";
this.wish=mmy;
doSomeThing();

}

結合以上的所有論述, 可以推測new Test()行為的偽代碼表示為:
創建一個新對象temp;
temp.constructor = Test;
temp.(base reference) = Test.prototype; // 這一句先於代碼體執行, 意味著構造函數里的this.xxx能訪問原型對象的屬性xxx
bind: this=temp; //將this綁定到temp對象
// 開始執行函數代碼
var mmy = "have money";
this.wish = mmy; // 為temp對象添加wish屬性
doSomeThing();
....
// 結束執行函數代碼
return temp;
這個未必會符合內部的二進制實現, 但卻能很好地解釋了JavaScript的特性.

9. javascript原型,原型鏈 有什麼特點

javascript原型,原型鏈特點:原型鏈實現了繼承。

JS中每個函數都存在有一個原型對象屬性prototype。並且所有函數的默認原型都是Object的實例。每個繼承父函數的子函數的對象都包含一個內部屬性proto。該屬性包含一個指針,指向父函數的prototype。若父函數的原型對象的_proto_屬性為再上一層函數。在此過程中就形成了原型鏈。

原型鏈的作用是用來實現繼承,比如我們新建一個數組,數組的方法就是從數組的原型上繼承而來的。

var arr = [];

arr.map === Array.prototype.map //arr.map

是從arr.__proto__上繼承下來的,arr.__proto__也就是Array.prototype。

(9)js刪除原型鏈中的屬性擴展閱讀:

1.JS中每個函數都存在有一個原型對象屬性prototype。並且所有函數的默認原型都是Object的實例。

2.每個繼承父函數的子函數的對象都包含一個內部屬性_proto_。該屬性包含一個指針,指向父函數的prototype。若父函數的原型對象的_proto_屬性為再上一層函數。在此過程中就形成了原型鏈。

3.原型鏈實現了繼承。原型鏈存在兩個問題:a 包含引用類型值的原型屬性會被所有實例共享。b 在創建子類型時,無法向超類型的構造函數中傳遞參數。

參考資料:網路-javascript

10. js裡面的繼承該怎麼理解,原型鏈是什麼概念,這方面的內容很重要麼

先來看一下原型
JavaScript的所有function類型的對象都有一個prototype屬性,這個prototype屬性本身
是一個object類型的對象,因此我們也可以給這個prototype對象添加任意的屬性和方法。
先看以下代碼
<script type=」text/javascript」>
Person = function(){
this.name = 「jack」;
};
Person.prototype.name = 「rose」;
p = new Person();
alert(p.name);//輸出jack
delete p.name;
alert(p.name);//輸出rose

</script>
由此可見當我們調用p.name時首先到p對象內部去查找name屬性如果沒有就去p對象的原型(prototype)中去查找name屬性再來看以下代碼
<script type=」text/javascript」>

Person = function(){
this.name = "jack";
};
Employee = function(){
this.name = "emp";
};
1 Employee.prototype = new Person();
2 Employee.prototype.name = "protoName";
Person.prototype.name = "rose";
e = new Employee();
alert(e.name);//輸出emp
delete e.name;
alert(e.name);//輸出protoName
delete Employee.prototype.name;
alert(e.name);//輸出rose
</script>
上面這段代碼可以看出調用e.name 首先到e對象內部查找可以找到emp,刪除後然後到e對象的原型中(prototype)去查找name屬性此時找到protoName再刪除,此時發現程序執行的流程是到Person的原型中去找出了rose, 由此可見代碼行1中Employee的原型關聯到了Person,相當於Person是Employee的父類。
讀者可能會發現上面這段描述寫的很敷衍
為什麼順序不是這樣
e對象內部->e對象原型->person對象內部->person對象原型
而是
e對象內部->e對象原型-> person對象原型
其實關鍵就在於1、2兩行代碼
做個實驗
調換1、2兩行代碼的位置

2 Employee.prototype.name = "protoName";
1 Employee.prototype = new Person();
再運行看看結果
alert(e.name);//輸出emp
delete e.name;
alert(e.name);//輸出jack
delete Employee.prototype.name;
alert(e.name);//輸出rose
</script>
這種輸出結果就好像如下順序
e對象內部-> person對象內部->person對象原型
如果你是真心想學習JS、以後想朝著這個方向發展,那麼你一定要來這個企鵝裙,前面前面是2九六,中間是五九一,最後面就是2九零,連起來就是完整的了,來這里可以這里學習經驗,得到專人解答,這樣你可以成長的更快!!!

為什麼有這樣的區別,關鍵就是這句話
Employee.prototype = new Person(); Employee的原型對象被賦值成了一個Person對象即Employee的原型被修改了,那麼寫在這句前面的Employee.prototype.name ="protoName";就沒有用了和刪除這句話效果一樣
那麼Employee.prototype.name也就理所應當等於person對象的name 給Employee.prototype.name賦值也就相當於給person對象的name屬性賦值那麼原來的jack就被覆蓋了原型鏈就是prototype對象的一條關系鏈這條鏈的末端就是Object對象的原型當調用對象的屬性或方法時首先會去對象內部查找,然後再依次順著原型鏈條一直找到Object

閱讀全文

與js刪除原型鏈中的屬性相關的資料

熱點內容
elonafix版本錯誤 瀏覽:70
百度網路推廣的形式 瀏覽:691
word左邊顯示提綱 瀏覽:810
台灣最好看的三極武工片 瀏覽:98
2021最新電影免費觀看的網址 瀏覽:629
韓國推理片在線播放 瀏覽:110
推薦韓日推理電影 瀏覽:989
華師大電影院 瀏覽:971
重生漢靈帝劉宏的小說 瀏覽:512
kktv怎麼調到網路電視 瀏覽:341
數據評價的方法有哪些 瀏覽:399
日韓好看電影 瀏覽:170
什麼怪談電影恐怖片 瀏覽:787
哪些渠道可以查看行業數據 瀏覽:88
無需下載免費在線觀看電影 瀏覽:230
真實里的馬尾女叫什麼名字 瀏覽:548
電腦網線區域網傳輸文件 瀏覽:805
win8文件批量重命名 瀏覽:843
大頭兒子小頭爸爸電影全部系列順序 瀏覽:676
iphone4s鑒別 瀏覽:562

友情鏈接