Professional JS(六-Understanding the object&&factory/constructor/prototype pattern)&enumerable

来源:互联网 发布:好用的粉底液推荐知乎 编辑:程序博客网 时间:2024/06/03 17:12

1.ECMA-262 defines an object as an “unordered collection of properties each of which contains a primitive value,object,or function”.

2.两种创建对象的方法:
①Object实例法:

var person=new Object();    person.name='yyc';    person.age=21;    person.sayName=function(){        return this.name;};

②对象字面量表示法:

var person={    name:'yyc',    age:21,    sayName:function(){        return this.name;    }};

3.想要修改属性默认的特性(attribute)必须使用ES5中Object.defineProperty()方法,该方法接受三个参数(属性所在对象/属性名/一个描述符对象-configurable-enumerable-writable-value)

var person={};Object.defineProperty(person,'name',{    value:'yyc'});person.name;//"yyc"person.name='Gerg';person.name;//"yyc"

4.访问器属性的四个特性:[[Configurable]]—[[Enumerable]]–[[Get]]–[[Set]]

var book={    _year:2004,    edition:1};Object.defineProperty(book,'year',{    get:funtion(){        return this.year;    },    set:funciton(value){        if(value>2004){            this._year=value;            this.edition+=(value-2004);        }    }});book.year=2017;book.edition;//14

5.创建访问器属性的两个遗留方法:defineGetter()/defineSetter()

6.如何定义多个属性—-Object.defineProperties()方法—属性:数据属性&访问器属性(accessor)

var book={};Object.defineProperties(book,{    _year:{ writable:true,value:2004 },    edition:{ writable:true,value:1},    year:{        get:function(){            return this._year;        },        set:function(value){            if(value>2004){                this._year=value;                this.edition+=(value-2004);            }        }    }});

7.读取属性的特性:Object.getOwnPropertyDescriptor(),包含两个参数(属性所在对象/要读取其描述符的属性名称)

var book={};Object.defineProperties(book,{    _year:{value:2004},    edition:{value:1},    year:{        get:function(){            return this._year;        },        set:function(value){            if(value>2004){                this._year=value;                this.edition+=(value-2004);            }        }    }});var descriptor=Object.getOwnPropertyDescriptor(book,'_year');descriptor.value;//2004descriptor.configurable;//falsedescriptor.get;//undefineddescriptor=Object.getOwnPropertyDescriptor(book,'year');descriptor.configurable;//falsedescriptor.enumerable;//falsetypeof(descriptor.get);//"function"

ES5的Object.getOwnPropertyDescriptor()方法只能用于实例属性,要像取得原型属性的描述符,必须直接在原型对象上调用该方法。

8.工厂模式:能解决相似对象构成的重复代码问题,但无法识别对象类型。

function createPerson(name,age,job){    var a=new Object();//在函数内部创建一个对象实例    a.name=name;    a.age=age;    a.job=job;    a.sayName=function(){        return this.name;    };    return a;//最后返回实例}var person1=createPerson('yyc',21,'Front-end engineer');var person2=createPerson('Greg',22,'student');

9.构造函数模式

function Person(name,age,job){    this.name=name;    this.age=age;    this.jog=job;    this.sayName=function(){        return this.name;    };}var person1=new Person('yyc',21,'Front-end engineer');var person2=new Person('Greg',22,'student');person1.sayName!=person2.sayName;//trueperson1.constructor==Person;//trueperson1 instanceof Person;//trueperson1 instanceof Object;//true

构造函数与其他函数的区别?—调用它们的方式不同。

function Person(name,age,job){ this.name=name;this.age=age;this.jog=job;this.sayName=sayName;}function sayName(){  return this.name;//如果对象中存在许多方法,你就需要定义多个全局函数,导致封装性差}var person1=new Person('yyc',21,'Front-end engineer');var person2=new Person('Greg',22,'student');

10.原型对象的好处:可以让所有实例对象共享它所包含的属性和方法。

11.每个函数都有一个原型属性prototype,这个属性是一个指针,指向一个对象。

function Person(){}Person.prototype.name='Greg';Person.prototype.age=21;Person.prototype.job='student';Person.prototype.sayName=function(){    return this.name;};var person1=new Person();person1.sayName();//"Greg"var person2=new Person();person2.sayName();//"Greg"person1.sayName==person2.sayName;//true

12.

Person.prototype.isPropertyOf(person1);Person.prototype.isPropertyOf(person2);

13.Object.getPrototypeOf()方法得到一个对象的原型。

Object.getPrototypeOf(Person1)==Person.prototype;//trueObject.getPrototypeOf(Person1).name;//"yyc"

14.调用person1.sayName()时,会先后执行两次搜索
①解析器问:“实例person1有sayName属性么”—-没有
②“person1的原型中有sayName属性么”—-有

15.当为一个对象实例添加一个属性时,该属性会屏蔽原型对象中保存的同名属性。

16.原型对象中的属性只能被屏蔽,而无法被修改,即使将新添加的属性值设置为null,也不会重新指向原型对象中的同名属性,但如果delete新添加的属性,那么该属性仍为”yyc”.

17.如何知道一个属性存在于实例还是原型中?
①hasOwnProperty()方法–如果存在实例中,返回true
②in—只要在实例或原型中存在该属性,返回true

function Person(){}Person.prototype.name='yyc';var person1=new Person();person1.hasOwnProperty('name');//falseperson1.name='Greg';person1.hasOwnProperty('name');//trueperson1.name;//"Greg"delete person1.name;//trueperson1.name;//"yyc"'name' in person1;//trueperson1.name='asan';'name' in person1;//trueperson1.name;//"asan"

18.如何判断一个属性仅存在于原型中:(hasOwnProperty()&&in)

function hasPrototypeProperty(object,name){    /*    hasOwnProperty()方法,仅当检测属性属于实例时返回true,而in检测   属性时,只要存在便返回true,无论存在于实例还是对象中。因此需要检测属性是否存在于原型时,使用如下语句。    */    return !object.hasOwnProperty(name)&&(name in object);}function Person(){}Person.prototype.name='yyc';var person1=new Person();hasPrototypeProperty(person1,'name');//trueperson1.name='asan';hasPrototypeProperty(person1,'name');//false

19.JS中,对象的属性有枚举和不可枚举之分,有enumerable属性值决定,可枚举性决定了这个属性能否被for…in遍历到。

var o={a:1,b:2};o.c=3;Object.defineProperty(o,'d',{    value:4,    enumerable:false});o.d;//4---虽然无法遍历到d,但是可以直接取该值。/*for...in循环:对象继承自原型对象的属性*/for(var key in o){    console.log(o[key]);}//1//2//3//undefined/*Object.keys()方法只包含其实例中的属性*/Object.keys(o);//(3) ["a", "b", "c"]JSON.stringify(o);//"{"a":1,"b":2,"c":3}"

20.

function Person(){}Person.prototype={    name:'yyc',    age:21,    job:'Front-end Enginner',    sayName:function(){        return this.name;    }};var friend=new Person();friend.constructor==Person;//false--使用简化方式后,实例的constrcutor不再指向Personfriend.constructor==Object;//truefriend instanceof Person;//truefriend instanceof Object;//truePerson.prototype={    constructor:Person};friend=new Person();friend.constructor==Person;//true---可人工设置constructor

21.对原型对象做任何修改都能立即从实例上反映出来

var friend=new Person();Person.prototype.sayHi=function(){    console.log('Hi');};friend.sayHi();//Hi

实例与原型之间的连接是指针,而不是一个副本。

22.

function Person(){}var asan=new Person();Person.prototype={    constructor:asan,    name:'surui',    age:22,    job:'student',    sayName:function(){        console.log('Hi');    }};asan.sayName();// Uncaught TypeError: asan.sayName is not a functionfunction Person(){}Person.prototype={    constructor:asan,    name:'surui',    age:22,    job:'student',    sayName:function(){        console.log('Hi');    }};var asan=new Person();asan.sayName();//Hi

重新构建一个原型对象,导致构造函数与另一个新的原型对象相连,但实例所连接的仍是初始的原型对象。因此没有sayHi这个函数,只有最初的constructor属性。

阅读全文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 公产房父母去世办公证怎么办 动迁过程中承租人去世了怎么办 公租房的房间带阳台怎么办 公租房合同到期没有社保怎么办 租房合同没有到期违约了怎么办 租房户到期不搬怎么办 公租房摇号摇到了又怎么办 公租房被清退会怎么办 公租房摇不到号怎么办 公租房到期不搬怎么办 租房到期租客不搬怎么办 房产证面积与实际不符怎么办 社保晚交了1天怎么办 个人社保忘交了怎么办 个人社保晚交了怎么办 医保晚交了几天怎么办 辞职后转为灵活就业养老怎么办 公司名称变更提取不了公积金怎么办 五险合一软件已经减员怎么办 法人社保不在投标单位怎么办 换工作单位后社保怎么办 在北京孩子没有一老一小怎么办 深户小孩怎么办社保卡 社保卡没办下来去医院住院怎么办 老年社保卡丢了怎么办 外墙掉瓷砖伤车伤人怎么办 医保卡姓名弄错了怎么办 走工伤和走社保怎么办 公司在朝阳社保在海淀怎么办 公司没缴纳个税怎么办 报个税工资报少了怎么办 医院预约单丢了怎么办 肛瘘手术后太疼怎么办 低位保肛手术后吻合口瘘怎么办 做完痔疮手术后大便困难怎么办 20岁长痔疮了怎么办 孕妇痔疮痒的难受怎么办 痔疮术后伤口不愈合怎么办 剖腹产液化伤口长的慢怎么办 内痔斑痕怎么办了能消化 油条面和稀了怎么办