最佳方式

原型模式与构造模式组合使用

先上代码:

function Person(name,age,salary){
this.name = name;
this.age = age;
this.salary = salary;
this.people = ["people1","people2"];
} Person.prototype = {
constructor:Person,
sayName:function(){
console.log(this.name);
}
} var p1 = new Person("name1","20","5000");
var p2 = new Person("name2","22","8000"); p1.people.push("people3");
console.log(p1.people);
console.log(p2.people);

运行结果:

Array [ "people1", "people2", "people3" ]
Array [ "people", "people" ]

这是创建对象最常用也是认同度最高的方式,把可共享的方法和属性放在prototype原型对象里面,把实例属性放在构造函数中。

动态原型模式

这种创建对象的模式,只写一个构造函数,而把原型放在构造函数中作为初始化用,这种结构就有点像java创建类一样,也是一种很好的创建对象的模式,我们来看一下:

function Person(name,age,salary){
this.name = name;
this.age = age;
this.salary = salary; if(typeof this.sayName != "function"){
Person.prototype.sayName = function(){
console.log("Hello, " + this.name);
}
Person.prototype.saySalary = function(){
console.log("My salary is " + this.salary);
}
}
} var p1 = new Person("name1","20","8000");
var p2 = new Person("name2","21","7000");
p1.sayName();
p1.saySalary(); p2.sayName();
p2.saySalary();

运行结果:

Hello, name1
My salary is 8000
Hello, name2
My salary is 7000

这种模式不能用字面量来重写原型。如果你尝试使用下面的代码来编写:

function Person(name,age,salary){
this.name = name;
this.age = age;
this.salary = salary; if(typeof this.sayName != "function"){ Person.prototype = {
constructor : Person,
sayName : function(){
console.log("Hello, " + this.name);
},
saySalary : function(){
console.log("My salary is " + this.salary);
}
}
}
} var p1 = new Person("name1","20","8000");
var p2 = new Person("name2","21","7000");
p1.sayName();
p1.saySalary(); p2.sayName();
p2.saySalary();

运行结果:

TypeError: p1.sayName is not a function

因为原型的重写是在创建了对象之后进行的,重写后的原型实际上是一个新的原型对象(重新创建一个,原来的还在,它们的constructor都指向Person),而实例的prototype指针还是指向原来的原型对象(里面没有其他属性和方法,因为属性和方法写在新的原型对象上),所以运行的时候,在实例对象中找不到sayName方法,在原型对象中也找不到sayName方法,即sayName未定义,所以在调用p1.sayName()方法时就报错,说sayName不是一个方法。

我们可以看下面的例子来深入理解一下:

function Person(){};

// 在之前创建
var p1 = new Person(); Person.prototype = {
constructor:Person,
name:"name1",
age:"20",
sayName:function(){
console.log(this.name);
}
}; // 在之后创建
var p2 = new Person();
p2.sayName(); //name1 p1.sayName(); //error

常用的方法

我们以下面这段代码为例:

function Person(name,age,salary){
this.name = name;
this.age = age;
this.salary = salary;
this.people = ["people1","people2"];
} Person.prototype = {
constructor:Person,
publicWork:"Teacher",
sayName:function(){
console.log(this.name);
}
} var p1 = new Person("name1","20","5000");
var p2 = new Person("name2","22","8000");

删除实例属性 delete

p1.publicWork = "Doctor";
console.log(p1.publicWork);
p1.publicWork = null;
console.log(p1.publicWork);
delete p1.publicWork;
console.log(p1.publicWork);

运行结果:

Doctor
null
Teacher

检测对象类型 instanceof

console.log(p1 instanceof Person); //true
console.log(p2 instanceof Person); //true

判断原型对象与实例之间是否联系 isPrototypeOf()

console.log(Person.prototype.isPrototypeOf(p1)); //true
console.log(Person.prototype.isPrototypeOf(p2)); //true

获得原型对象 Object.getPrototypeOf()

console.log(Object.getPrototypeOf(p1) == Person.prototype); //true
console.log(Object.getPrototypeOf(p2).publicWork); //Teacher

注意:这是 ECMAScript5 的新方法,IE9+、其他主流浏览器支持。

判断属性是否存在于原型对象中

//函数作用:判断属性是否存在于原型对象中
function isInPrototype(obj,param){
if((param in obj) && !obj.hasOwnProperty(param)){
return true;
}else{
return false;
}
} console.log(isInPrototype(p1,"publicWork")); //true
console.log(isInPrototype(p2,"name")); //false
  • hasOwnProperty() 可以检测属性是否在实例中
  • in 可以检测属性是否存在,无论是在实例中还是在原型对象中

通过以上方法的结合,即可判断属性是否存在于原型对象中。

获得可枚举的属性和方法 Object.keys()

先要了解:对于系统内置的属性一般是不可枚举的,如果重新创建覆盖原来的属性,那么就变成可枚举。

console.log(Object.keys(p1));
console.log(Object.keys(Person.prototype));

运行结果:

Array [ "name", "age", "salary", "people" ]
Array [ "constructor", "publicWork", "sayName" ]

其中constructor为覆盖的属性,所以变为可枚举。

参考

  • 《JavaScript高级程序设计》

JavaScript创建对象的更多相关文章

  1. Javascript 创建对象方法的总结

    最近看了一下<Javascript高级程序设计(第三版)>,这本书很多人都推荐,我也再次郑重推荐一下.看过之后总得总结一下吧,于是我选了这么一个主题分享给大家. 使用Javascript创 ...

  2. javascript创建对象的几种方式

    javascript创建对象简单的说,无非就是使用内置对象或各种自定义对象,当然还可以用JSON:但写法有很多种,也能混合使用.主要为下面几种:1.对象字面量的方式 person={firstname ...

  3. javascript创建对象的方法总结

    Javascript创建对象 最简单的方法:创建object实例. var person=new Object(); person.name="Joey";person.age=2 ...

  4. javascript创建对象的相关问题

    javascript创建对象的方法有很多种,一般来说,推荐使用对象字面量来创建对象. 对象构造函数捕捉 使用new Object来创建对象,可能会带来一些问题: var o = new Object( ...

  5. JavaScript创建对象(三)——原型模式

    在JavaScript创建对象(二)——构造函数模式中提到,构造函数模式存在相同功能的函数定义多次的问题.本篇文章就来讨论一下该问题的解决方案——原型模式. 首先我们来看下什么是原型.我们在创建一个函 ...

  6. Javascript 创建对象的三种方法及比较【转载+整理】

    https://developer.mozilla.org/zh-CN/docs/JavaScript/Guide/Inheritance_and_the_prototype_chain 本文内容 引 ...

  7. JavaScript创建对象的6种方式

    JavaScript创建对象简单的说,无非就是使用内置对象(Object)或各种自定义对象,当然还可以用JSON,但写法有很多种,也能混合使用. 1.对象字面量的方式 person = {name : ...

  8. JavaScript 创建对象的七种方式

    转自:xxxgitone.github.io/2017/06/10/JavaScript创建对象的七种方式/ JavaScript创建对象的方式有很多,通过Object构造函数或对象字面量的方式也可以 ...

  9. Javascript创建对象几种方法解析

    Javascript创建对象几种方法解析 Javascript面向对象编程一直是面试中的重点,将自己的理解整理如下,主要参考<Javascript高级程序设计 第三版>,欢迎批评指正. 通 ...

  10. JavaScript创建对象的几种 方式

    //JavaScript创建对象的七种方式 //https://xxxgitone.github.io/2017/06/10/JavaScript%E5%88%9B%E5%BB%BA%E5%AF%B9 ...

随机推荐

  1. 多光谱图像数据库, Multispectral images databses

    1. https://scien.stanford.edu/index.php/hyperspectral-image-data/ 2. http://www.cs.columbia.edu/CAVE ...

  2. Html5 杂记

    (一):html5的声明 <!DOCTYPE html> 注意:声明必须是 HTML 文档的第一行,位于 <html> 标签之前.   声明不是 HTML 标签:它是指示 we ...

  3. HTML5在canvas中绘制复杂形状附效果截图

    HTML5在canvas中绘制复杂形状附效果截图 一.绘制复杂形状或路径 在简单的矩形不能满足需求的情况下,绘图环境提供了如下方法来绘制复杂的形状或路径. beginPath() : 开始绘制一个新路 ...

  4. tyvj1106 登山

    背景     在很久很久以前,有一个动物村庄,那里是猪的乐园(^_^),村民们勤劳.勇敢.善良.团结……    不过有一天,最小的小小猪生病了,而这种病是极其罕见的,因此大家都没有储存这种药物.所以晴 ...

  5. There are no resources that can be added or removed from the server

    第1步.新建一个“Dynamic Web Project” 第2步.把新建项目里面的.project文件和.settings文件夹复制到导入的那个项目里面. 第3步.把web projiect set ...

  6. 微信公众平台推出"微信保护"提升微信账号安全 附微信保护开启教程

    前两天小美女的微信公众平台要群发消息时提示需要绑定手机才能操作,当时还以为是动态ip的问题,今天微信公众平台安全中心就说升级了,原来那时已经在公测了.微信公众平台推出"微信保护", ...

  7. 【Alpha】Daily Scrum Meeting第一次

    一.本次Daily Scrum Meeting主要内容 代码任务细分 服务器搭建 每个人时间分配及安排 二.项目进展 学号尾数 今天做的任务 任务完成度 明天要做的任务 612 写代码框架 30% 主 ...

  8. PL/SQL Developer 连接 64位Oracle 服务端 解决方案

    PL/SQL是32位程序,只能通过32位的Oracle驱动连接Oracle服务器.如果Oracle服务器是64位的,那么只能通过需要通过一个32位的Oracle客户端,来搭建连接. 到官网下载一个客户 ...

  9. str.format

    #使用str.format()函数 #使用'{}'占位符 print('I\'m {},{}'.format('Hongten','Welcome to my space!')) >>&g ...

  10. .net 根据银行卡获取银行信息

    using System; using System.Collections.Generic; using System.Linq; using System.Web; /// <summary ...