最佳方式

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

先上代码:

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. Win7普通版-X86-SP1-ios-旗舰版安装

    ------------------------------- 自己的电脑是X64Win7系统.Acer电脑----->>现在改装成  Win7普通版-X86-SP1-ios-旗舰版安装 ...

  2. AXIS 调用 webservice服务时传递 服务器验证需要的用户名密码

    System.setProperty("javax.net.ssl.trustStore", T.class.getResource(".").getPath( ...

  3. XML Schema and XMLspy notes

    Introduction An xml documents consists of elements, attributes and text. There are two structures in ...

  4. C/C++ 静态链接库(.a) 与 动态链接库(.so)

    平时我们写程序都必须 include 很多头文件,因为可以避免重复造轮子,软件大厦可不是单靠一个人就能完成的.但是你是否知道引用的那些头文件中的函数是怎么被执行的呢?这就要牵扯到链接库了! 库有两种, ...

  5. MVC项目使用easyui的filebox控件上传文件

    开发环境:WIN10+IE11,浏览器请使用IE10或以上版本 开发技术框架MVC4+JQuery Easyui+knockoutjs 效果为弹出小窗体,如下图 1.前端cshtml文件代码(只包含文 ...

  6. SQL/T-SQL实例参考

    ,D.[Score] B_Score ,'Distince'= CASE WHEN C.Score > D.Score THEN C.[Score] - D.[Score] WHEN C.Sco ...

  7. Python pydoc.py

    1. 查看帮助,我们可以在python命令行交互环境下用 help函数,比如: 查看 math 模块: >>> help('math')Help on built-in module ...

  8. js 连续赋值。。理解不了,先占坑

    http://www.cnblogs.com/xxcanghai/p/4998076.html

  9. mysql ERROR 1045 (28000): 错误解决办法

    ERROR 1045 (28000): Access denied for user 'ODBC'@'localhost' (using password: NO) ERROR 1045 (28000 ...

  10. JDK7 tomcat6 各种环境变量配置

    JDK JAVA_HOME:jdk路径,bin目录上一层 Path:%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin CLASSPATH:.;%JAVA_HOME%\lib;%J ...