首页 > 其他分享 >更简单的原型语法和原型语法的动态性

更简单的原型语法和原型语法的动态性

时间:2023-02-14 15:36:55浏览次数:29  
标签:console log 动态性 语法 Person 原型 constructor prototype true


更简单的原型语法 为减少不必要的输出,也从视觉上更好的封装原型的功能,用一个包含所有属性和方法的对象字面量来重写整个原型对象:

function Person() {
}

Person.prototype = {
name : "Hongbin",
age : 21,
sex : true,
sayHello : function () {
console.log("Hello "+this.name);
}
};

存在问题:上面相当于重写了默认的Person.prototype,prototype中的constructor属性也随之改变,不在指向Person。此时instanceof操作符还能返回正确的结果,但通过constructor已经无法确定对象的类型了:

var person1 = new Person();

console.log(person1 instanceof Person);//true
console.log(person1.constructor == Person);//false
console.log(person1.constructor == Object);//true

如果constructor指向整的很重要,可以手动设置值

Person.prototype = {
constructor : Person,
name : "Hongbin",
age : 21,
sex : true,
sayHello : function () {
console.log("Hello "+this.name);
}
};

var person2 = new Person();
console.log(person2.constructor == Person);//true

但以这种方式设置constructor的属性,导致constructor的[[Enumerable]]值变成了true,默认情况下值为false,如果使用的兼容ECMAScript5的JavaScript引擎,可以用Object.defineProperty()方法设置constructor属性

Object.defineProperty(Person.prototype,'constructor',{
value:Person,
enumerable:false
});
// console.log(Object.getOwnPropertyDescriptors(Person.prototype));//constructor: {writable: true, enumerable: false, configurable: true, value: ƒ}

到此解决constructor指向因重置prototype属性而产生变化问题

原型链的动态性:原型查找是一次搜索行为,因此我们对原型对象做的任何操作都能立刻反映到实例上–即使先创建了实例后修改原型也是如此:

在设置prototype.name为一个新的值之前打印的实例属性也发生变化

更简单的原型语法和原型语法的动态性_原型对象


下图中,我们可以看到在constructor没有设置的时候创建的person1并没有任何改变,甚至constructor依旧没有指向Person,是因为它定义在constructor指向Person之前,

更简单的原型语法和原型语法的动态性_javascript_02


我们将person2也放到constructor指向Person之前定义发现

更简单的原型语法和原型语法的动态性_操作符_03


person2也出现了和person1一样的抓概况,对比一下

更简单的原型语法和原型语法的动态性_javascript_04


person2又恢复正常,

通过person1和person2对比我们发现:

重写的原型对象切断了现有原型与任何之前已经存在的对象实例之间的联系;它们引用的仍是最初的原型
//更简单的原型语法 为减少不必要的输出,也从视觉上更好的封装原型的功能,用一个包含所有属性和方法的对象字面量来重写整个原型对象:
function Person() {
}

Person.prototype = {
name : "Hongbin",
age : 21,
sex : true,
sayHello : function () {
console.log("Hello "+this.name);
}
};
//问题:上面相当于重写了默认的Person.prototype,prototype中的constructor属性也随之改变,不在指向Person。此时instanceof操作符还能返回正确的结果,但通过constructor已经无法确定对象的类型了:
var person1 = new Person();

console.log(person1 instanceof Person);//true
console.log(person1.constructor == Person);//false
console.log(person1.constructor == Object);//true
//如果constructor指向整的很重要,可以手动设置值
Person.prototype = {
constructor : Person,
name : "Hongbin",
age : 21,
sex : true,
sayHello : function () {
console.log("Hello "+this.name);
}
};

var person2 = new Person();
console.log(person2.constructor == Person);//true
//但以这种方式设置constructor的属性,导致constructor的[[Enumerable]]值变成了true,默认情况下值为false,如果使用的兼容ECMAScript5的JavaScript引擎,可以用Object.defineProperty()方法设置constructor属性
Object.defineProperty(Person.prototype,'constructor',{
value:Person,
enumerable:false
});
// console.log(Object.getOwnPropertyDescriptors(Person.prototype));//constructor: {writable: true, enumerable: false, configurable: true, value: ƒ}
//到此解决constructor指向因重置prototype属性而产生变化问题

//原型链的动态性:原型查找是一次搜索行为,因此我们对原型对象做的任何操作都能立刻反映到实例上--即使先创建了实例后修改原型也是如此:
console.log(person2);
Person.prototype.name = "new name!";
console.log(person2);//new name!

console.log(person1);//Hongbin
console.log(person1.constructor == Person);//false
//person1并没有改变,constructor也是如此,是因为它定义在constructor指向Person之前


标签:console,log,动态性,语法,Person,原型,constructor,prototype,true
From: https://blog.51cto.com/u_15964288/6056965

相关文章

  • vue-day02——插值语法、文本指令、属性指令、事件指令、class和style、条件渲染、列
    目录昨日回顾今日内容1插值语法1.1mvvm演示1.1插值语法2文本指令3属性指令4事件指令5class和style6条件渲染7列表渲染补充:作业昨日回顾#1put,post提交的jso......
  • XML 语法
    1、XML标签对大小写敏感2、XML元素都必须要有关闭标签这样的话,关闭标签啥的都要大小写对应了。3、XML文档必须有根元素。根元素定义:是其他所有元素的父元素4、XM......
  • Java基础语法2
     作者:Mercury_Lc​​​​SDUTJava基础语法练习2​​I      C语言实验——打印菱形(SDUT1174)importjava.util.Scanner;publicclassMain{publicstaticvoi......
  • Java基础语法n
    BK     分段函数(SDUT2257)importjava.util.*;publicclassMain{publicstaticvoidmain(String[]args){Scannersc=newScanner(System.in);......
  • Java基础语法3
    排序(SDUT1582)importjava.util.*;publicclassMain{publicstaticvoidmain(String[]args){Scannersc=newScanner(System.in);intn;inta[]=new......
  • 【nginx】Nginx if语法不支持if条件的逻辑与&&逻辑或|| 运算 ,而且不支持if的嵌套语法
    条件判断Nginx语法不支持if条件的逻辑与&&逻辑或||运算,而且不支持if的嵌套语法。需要借助变量来实现嵌套语法或多条件判断location/{set$flag0;if($hos......
  • MarkDown语法说明
    一、markdown基础1.标题使用#号标记,可以表示1-6级标题,随#个数递增。如:#一级标题##二级标题###三级标题####四级标题#####五级标题######六级标题注:最后一......
  • Java基础语法
    注释注释是写在程序中对代码进行解释说明的文字,方便自己和他人查看,以便理解程序的IDEA中的快捷键是行注释CTRL/和块注释CTRLSHIFT/packagecom.wushf.note;publicc......
  • JavaScript的原型、原型链、异步与单线程复习回顾
     原型和原型链有对象的地方就有原型,每个对象都会在其内部初始化一个属性,就是prototype(原型),原型中存储共享的属性和方法。当我们访问一个对象的属性时,js引擎会先看当......
  • mysql基础查询语法
    ......