导航:首页 > 编程语言 > 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删除原型链中的属性相关的资料

热点内容
贵阳有情侣座的电影院 浏览:983
天堂网在线免费观看 浏览:733
win10左面文件在哪个夹 浏览:549
成都动游天下网络技术有限公司 浏览:460
怎样一键更改文件格式mkv 浏览:994
都市重生收母收姐妹txt 浏览:99
appstore不能搜索 浏览:794
看客电影 浏览:57
关于蛇变人的香港电影 浏览:769
中文肉电影 浏览:971
萧楼晋江 浏览:308
电影院电影布 浏览:294
无广告免费电影网址 浏览:104
男主通过药物控制女主 浏览:763
wordgirl 浏览:387
数据可视化技术指标是什么 浏览:472
淘宝全屏海报显示代码 浏览:715
缉魂台湾原版130分钟百度云 浏览:977
香港三级古装喜剧电影 浏览:753
可以探知生命体的触手的电影 浏览:102

友情链接