300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > JavaScript高级程序设计读书笔记(第6章面向对象的程序设计之创建对象)

JavaScript高级程序设计读书笔记(第6章面向对象的程序设计之创建对象)

时间:2021-10-22 04:00:01

相关推荐

JavaScript高级程序设计读书笔记(第6章面向对象的程序设计之创建对象)

独角兽企业重金招聘Python工程师标准>>>

面向对象语言都有“类”的概念,而通过类可以创建任意多个具有相同属性和方法的对象。 JS中没有“类”的概念,它实现“对象”的方式是通过定义函数,函数里面有属性和方法。 以下开始将创建对象的几种方式。

1.工厂模式

function createPerson(name,age,job){var o=new Object();o.name=name;o.age=age;o.job=job;o.showJob=function(){console.log(this.job);}return o;}var p1=createPerson("Annie",18,"Teacher");var p2=createPerson("Bob",20,"Jser");console.log(p1);//Object {name: "Annie", age: 18, job: "Teacher", showJob: function}console.log(p2);//Object {name: "Bob", age: 20, job: "Jser", showJob: function}p2.name="Cindy";console.log(p2);//Object {name: "Cindy", age: 20, job: "Jser", showJob: function}

优:解决了JS中创建多个相似对象的问题。

缺:没有解决对象识别问题(即怎么知道一个对象的类型,JS对象类型的确定)

2.构造函数模式

function Person(name,age,job){//构造函数的函数名首字母大写this.name=name;this.age=age;this.job=job;this.showJob=function(){console.log(this.job);}}var p1=new Person("Annie",18,"Teacher");var p2= new Person("Bob",20,"JSer");console.log(p1);//Person {name: "Annie", age: 18, job: "Teacher", showJob: function}console.log(p2);//Person {name: "Bob", age: 20, job: "JSer", showJob: function}p1.showJob();//Teacher

p1和p2分别保存着Person的一个不同的实例,这两个对象都有一个constructor(构造函数)属性,指向Person。

console.log(p1.constructor==Person); //trueconsole.log(p2.constructor==Person); //true

检测对象类型:

//检测对象类型console.log(p1 instanceof Person);//trueconsole.log(p1 instanceof Object);//trueconsole.log(p2 instanceof Person);//trueconsole.log(p2 instanceof Object);//true

优:解决了对象识别问题。

缺: 此时每个方法都要在每个实例上面重新创建一次,考虑到有this对象,可通过把函数定义转移到构造函数外部来解决这个问题:

function Person(name,age,job){//构造函数的函数名首字母大写this.name=name;this.age=age;this.job=job;this.showJob=showJob;//this.showJob=function(){//console.log(this.job);//}}//可把函数定义转移到构造函数外部function showJob(){console.log(this.job);}var p1=new Person("Annie",18,"Teacher");var p2= new Person("Bob",20,"JSer");console.log(p1);//Person {name: "Annie", age: 18, job: "Teacher", showJob: function}console.log(p2);//Person {name: "Bob", age: 20, job: "JSer", showJob: function}p1.showJob();//Teacher

但是如此一来,在全局作用域中定义的函数实际上只能被某个对象调用,这让全局作用域有些名不副实。并且,如果对象需要定义很多方法,就要定义很多个全局函数,于是这个自定义的引用类型就毫无封装性可言。

3.原型模式 原型对象可让所有对象实例共享它所包含的属性和方法。

function Person(){} Person.prototype.name="Annie";Person.prototype.age=18;Person.prototype.job="Teacher";Person.prototype.showJob=function(){console.log(this.job);}var p1=new Person();console.log(p1);//Person {name: "Annie", age: 18, job: "Teacher", showJob: function}p1.showJob();//Teacher

确定对象(父对象和子对象)之间是否存在原型关系的两种判断

console.log(Person.prototype.isPrototypeOf(p1));//trueconsole.log(Object.getPrototypeOf(p1) == Person.prototype);//true

判断访问的是实例属性还是原型属性

//hasOwnPrototy()方法判断访问的是实例属性还是原型属性//只在给定属性存在于对象实例中,才会返回trueconsole.log(p1.hasOwnProperty("name"));//falsep1.name="Anna";console.log(p1.name);//Anna,来自实例console.log(p1.hasOwnProperty("name"));//truedelete p1.name;//删除实例中的name属性,恢复了对原型中name属性的连接console.log(p1.name);//Annie,来自原型console.log(p1.hasOwnProperty("name"));//false//hasOwnPrototy()结合in判断访问的是实例属性还是原型属性function hasOwnPrototyFunction(object,name){return !object.hasOwnProperty(name)&&(name in object);}console.log(hasOwnPrototyFunction(p1,"Annie"));//false

取得对象上的可枚举实例属性,object.key()

function Person(){}Person.prototype.name="Cindy";Person.prototype.age=14;Person.prototype.job="Csser";Person.prototype.showJob=function(){console.log(this.job);}var keys=Object.keys(Person.prototype);console.log(keys);//["name", "age", "job", "showJob"] var p1=new Person();p1.name="David";p1.age=21;var p1Keys=Object.keys(p1);console.log(p1Keys);//["name", "age"]

取得对象上的所有实例属性,无论是否可枚举,Object.getOwnPropertyNames()。 原生的constructor属性不可枚举。

var ownKeys=Object.getOwnPropertyNames(Person.prototype);console.log(ownKeys);//"constructor", "name", "age", "job", "showJob"]

优:保证的封装性。

缺:对于包含了引用类型值的函数来说,共享会带来一些问题:

function Person(){}Person.prototype={constructor:Person,name:"Annie",age:18,job:"Teacher",friends:["Cindy","David"],showJob:function(){console.log(this.job);}}var p1=new Person();var p2=new Person();p1.friends.push("Ella");console.log(p1.friends);//["Cindy", "David", "Ella"] console.log(p2.friends);//["Cindy", "David", "Ella"]

4.组合使用构造函数和原型模式(创建自定义类型常见的方式)。

function Person(name,age,job){this.name=name;this.age=age;this.job=job;this.friends=["Cindy","David"]}Person.prototype={constructor:Person,showJob:function(){console.log(this.job);}}var p1=new Person("Annie",18,"Teacher");var p2=new Person("Cindy",22,"Jser");p1.friends.push("Ella");console.log(p1.friends);//["Cindy", "David", "Ella"] console.log(p2.friends);//["Cindy", "David"]

5.动态原型模式

function Person(name,age,job){//属性this.name=name;this.age=age;this.job=job;//方法if(typeof this.showJob != "function"){Person.prototype.showJob=function(){console.log(this.job);};}}var p1=new Person("Annie",17,"Teacher");p1.showJob();//Teacher

6.寄生构造函数模式 寄生构造函数模式在一般情况下跟工厂模式是一模一样的,但是在如下特殊情况下:

//寄生构造函数模式function specialArray(){//创建数组var values=new Array();//添加值values.push.apply(values,arguments);//添加方法values.toPipedString=function(){return this.join("|");}//返回数组return values;}var colors=new specialArray("red","green","blue");console.log(colors.toPipedString());//red|green|blue

7.稳妥构造函数模式

function Person(name,age,job){var o=new Object;//定义私有变量和函数//....//添加方法o.showJob=function(){console.log(job);};return o;}var p1=new Person("Annie",18,"Teacher");p1.showJob();//Teacher;

除了调用showJob()外,没有别的方式可以访问其他数据成员。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。