javascript面向对象系列2——创建对象的9种方式

【1】使用Object构造函数
  [缺点]使用同一个接口创建很多对象,会产生大量重复代码

var person = new Object();
    person.name = "Nicholas";
    person.age = 29;
    person.job = "Software Engineer";
    person.sayName = function(){
      alert(this.name);
  }

【2】使用对象字面量
  [缺点]使用同一个接口创建很多对象,会产生大量重复代码

var person = {
    name: "Nicholas",
    age : 29,
    job: "Software Engineer",
    sayName: function(){
        alert(this.name);
    }
};

【3】工厂模式:抽象了创建具体对象的过程,考虑到ECMAScript中无法创建类,开发人员就发明了一种函数,用函数来封装以特定接口创建对象的细节
  [缺点]解决了创建多个相似对象的问题,但没有解决对象识别的问题

function createPerson(name,age,job){
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayname = function(){
        alert(this.name);
    }
    return o;
}
var person1 = createPerson(‘Nicholas‘,29,‘software Engineer‘);
var person2 = createPerson(‘greg‘,27,‘doctor‘);

【4】构造函数模式:没有显式地创建对象,直接将属性和方法赋给了this对象,没有return语句
  [缺点]每个方法都要在每个实例上重新创建一遍

function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.jog = job;
    this.sayName = function(){
        alert(this.name);
    };
    //与声明函数在逻辑上是等价的
    //this.sayName = new Function(‘alert(this.name)‘);

}
var person1 = new Person("Nicholas",29,"software Engineer");
var person2 = new Person("Greg",27,"doctor");

  【4.1】构造函数拓展模式:把函数定义转移到构造函数外部

    [缺点1]在全局作用域中定义的函数实际上只能被某个对象调用,这让全局作用域有点名不副实
    [缺点2]若对象需要定义很多方法,就要定义很多全局函数,这个自定义引用类型就没有封装性可言

function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = sayName;
}
function sayName(){
    alert(this.name);
}
var person = new Person(‘小火柴‘,‘20‘,‘student‘)
person.sayName();
console.log(Person);

【5】原型模式:我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。如果按照字面意思来理解,prototype就是通过调用构造函数而创建的对象实例的原型对象

function Person(){
    Person.prototype.name = "Nicholas";
    Person.prototype.age = 29;
    Person.prototype.job = "software Engineer";
    Person.prototype.sayName = function(){
        alert(this.name);
    }
}
var person1 = new Person();
person1.sayName();//"Nicholas"
var person2 = new Person();
person2.sayName();//"Nicholas"
alert(person1.sayName == person2.sayName);//true

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

    [缺点]以这种方式重设constructor属性会导致它的[[Enumerable]]特性被设置为true,默认情况下原生的constructor属性是不可枚举的

function Person(){};
Person.prototype = {
    constructor : Person,
    name: "Nicholas",
    age: 29,
    job: "software Engineer",
    sayName : function(){
        alert(this.name);
    }
};

  【5.2】解决enumerable问题的原型模式

function Person(){};
Person.prototype = {
    name: "Nicholas",
    age: 29,
    job: "software Engineer",
    sayName : function(){
        alert(this.name);
    }
};
Object.defineProperty(Person.prototype,"constructor",{
    enumerable : false,
    value : Person
});

  [原型模式缺点1]重写原型对象切断了现有原型与已存在对象实例之间的联系,它们引用的仍是最初的原型。

function Person(){}
var friend = new Person();
Person.prototype = {
    constructor: Person,
    name: "Nicholas",
    age: 29,
    job: "Software Engineer",
    sayName: function(){
        alert(this.name);
    }
};
friend.sayName();//error

  [原型模式缺点2]引用类型属性的共享性问题突出

function Person(){}
Person.prototype = {
    constructor: Person,
    name: "Nicholas",
    age: 29,
    job: "Software Engineer",
    friend : ["shelby","Court"],
    sayName: function(){
        alert(this.name);
    }
};
var person1 = new Person();
var person2 = new Person();
person1.friends.push("Van");
alert(person1.friends);//["shelby","Court","Van"];
alert(person2.friends);//["shelby","Court","Van"];
alert(person1.friends === person2.friends);//true

【6】组合模式:组合使用构造函数模式和原型模式是创建自定义类型的最常见方式。构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性。这种混成模式还支持向构造函数传递参数,是用来定义引用类型的一种默认模式

function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.friends = ["shelby","Court"];
}
Person.prototype = {
    constructor: Person,
    sayName : function(){
        alert(this.name);
    }
}
var person1 = new Person("Nicholas",29,"Software Engineer");
var person2 = new Person("Greg",27,"Doctor");
person1.friends.push("Van");
alert(person1.friends);// ["shelby","Court","Van"];
alert(person1.friends);// ["shelby","Court"];
alert(person1.friends === person2.friends);//false
alert(person1.sayName === person2.sayName);//true

【7】动态原型模式:把所有信息都封装在构造函数中,通过在构造函数中初始化原型(仅在必要情况下),又保持了同时使用构造函数和原型的优点。换句话说,可以通过检查某个存在的方法是否有效,来决定是否要初始化原型。
  [注意]使用动态原型模式时,不能使用对象字面量重写原型。如果在已经创建了实例的情况下重写原型,那么就会切断现有实例与新实例之间的联系

function Person(name,age,job){
    //属性
    this.name = name;
    this.age = age;
    this.job = job;
    //方法
    if(typeof this.sayName != "function"){
        Person.prototype.sayName = function(){
            alert(this.name);
        };
    }
}
var friend = new Person("Nicholas",29,"Software Engineer");
friend.sayName();

【8】寄生构造函数模式:创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后再返回新创建的对象

function Person(name,age,job){
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function(){
        alert(this.name);
    };
    return o;
}
var friend = new Person("Nicholas",29,"Software Engineer");
friend.sayName();//"Nicholas"

  【寄生构造函数模式应用】创建一个具有额外方法的特殊数组。由于不能直接修改Array构造函数,因此可以使用这个模式

function SpecialArray(){
    //创建数组
    var values = new Array();
    //添加值
    values.push.apply(values,argumens);
    //添加方法
    values.toPipedString = function(){
        return this.join(‘|‘);
    };
    //返回数组
    return values;
}
var colors = new SpecialArray("red","blue","green");
alert(colors.toPipedString());//"red|blue|green"    

【9】稳妥构造函数模式:所谓稳妥对象指没有公共属性,而且其方法也不引用this的对象。稳妥对象最适合在一些安全环境中(这些环境会禁止使用this和new)或者在防止数据被其他应用程序改动时使用。

function Person(name,age,job){
    //创建要返回的对象
    var o = new Object();
    //可以在这里定义私有变量和函数
    //添加方法
    o.sayName = function(){
        alert(name);
    };
    //返回对象
    return o;
}
//在稳妥模式创建的对象中,除了使用sayName()方法之外,没有其他方法访问name的值
var friend = Person("Nicholas",29,"Software Engineer");
friend.sayName();//"Nicholas"
时间: 2025-01-06 02:22:26

javascript面向对象系列2——创建对象的9种方式的相关文章

javascript面向对象系列5——知识点(原型和原型链)

基本概念 [原型链]每个构造函数都有一个对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针.那么,如果原型对象等于另一个原型的实例,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针.如果另一个原型又是另一个原型的实例,那么上述关系依然成立.如此层层递进,就构成了实例与原型的链条. [原型对象]这个对象包含可以由特定类型的所有实例共享的属性和方法.所有引用类型默认都继承了Object,而这个继承也是通过原型链实现

javascript面向对象系列第三篇——实现继承的3种形式

前面的话 学习如何创建对象是理解面向对象编程的第一步,第二步是理解继承.开宗明义,继承是指在原有对象的基础上,略作修改,得到一个新的对象.javascript主要包括类式继承.原型继承和拷贝继承这三种继承方式.本文是javascript面向对象系列第三篇——实现继承的3种形式 类式继承 大多数面向对象的编程语言都支持类和类继承的特性,而JS却不支持这些特性,只能通过其他方法定义并关联多个相似的对象,如new和instanceof.不过在后来的ES6中新增了一些元素,比如class关键字,但这并不

js中面向对象(创建对象的几种方式)

1.面向对象编程(OOP)的特点: 抽象:抓住核心问题 封装:只能通过对象来访问方法 继承:从已有的对象下继承出新的对象 多态:多对象的不同形态 注:本文引用于 http://www.cnblogs.com/yuxingyoucan/p/5797142.html 一.创建对象的几种方式 javascript 创建对象简单的来说,无非就是使用内置对象或各种自定义对象,当然还可以使用JSON,但写法有很多,也能混合使用. 1.工厂方式创建对象:面向对象中的封装函数(内置对象) function cr

JavaScript 创建对象的七种方式

转自:xxxgitone.github.io/2017/06/10/JavaScript创建对象的七种方式/ JavaScript创建对象的方式有很多,通过Object构造函数或对象字面量的方式也可以创建单个对象,显然这两种方式会产生大量的重复代码,并不适合量产.接下来介绍七种非常经典的创建对象的方式,他们也各有优缺点. 工厂模式 1 function createPerson(name, job) { 2 var o = new Object() 3 o.name = name 4 o.job

0145 JavaScript创建对象的三种方式 之 字面量:创建,访问对象的属性&方法,变量、属性、函数、方法总结

在 JavaScript 中,现阶段我们可以采用三种方式创建对象(object): 利用字面量创建对象 利用 new Object 创建对象 利用构造函数创建对象 5.2.1 利用字面量创建对象 5.2.1.1 创建 使用对象字面量创建对象:{ }. 就是花括号 { } 里面包含了表达这个具体事物(对象)的属性和方法: { } 里面采取键值对的形式表示 键:相当于属性名 值:相当于属性值,可以是任意类型的值(数字类型.字符串类型.布尔类型,函数类型等) 代码如下: var star = { na

OOP 创建对象的7种方式

JavaScript OOP 创建对象的7种方式 我写JS代码,可以说一直都是面向过程的写法,除了一些用来封装数据的对象或者jQuery插件,可以说对原生对象了解的是少之又少.所以我拿着<JavaScript高级程序设计 第3版>恶补了一下,这里坐下总结笔记,属于菜鸟级别,大神请直接无视. 1.工厂模式 1 /** 2 * 工厂模式 3 */ 4 function createPerson(name,age,job){ 5 var o = new Object(); 6 o.name = na

第184天:js创建对象的几种方式总结

1.面向对象编程(OOP)的特点: 抽象:抓住核心问题 封装:只能通过对象来访问方法 继承:从已有的对象下继承出新的对象 多态:多对象的不同形态 一.创建对象的几种方式 javascript 创建对象简单的来说,无非就是使用内置对象或各种自定义对象,当然还可以使用JSON,但写法有很多,也能混合使用. 1.工厂方式创建对象:面向对象中的封装函数(内置对象) 1 function createPerson(name){ 2 //1.原料 3 var obj=new Object(); 4 //2.

创建对象的第二种方式:克隆clone,要实现Cloneable接口

1 ackage com.wisezone.clone; 2 3 /** 4 * 空接口: 5 * 标识,告诉JVM,通行 6 * 1.克隆 7 * 2.序列化 8 * 9 * 创建对象的第二种方式:克隆clone,要实现Cloneable 10 * @author 王东海 11 * @2017年4月15日 12 */ 13 public class TestClone implements Cloneable 14 { 15 public String name; 16 17 public s

Java中创建对象的几种方式

Java中创建对象的五种方式: 作为java开发者,我们每天创建很多对象,但是我们通常使用依赖注入的方式管理系统,比如:Spring去创建对象,然而这里有很多创建对象的方法:使用New关键字.使用Class类的newInstance方法.使用Constructor类的newInstance方法.使用Clone方法.使用反序列化. 使用new关键字:这是我们最常见的也是最简单的创建对象的方式,通过这种方式我们还可以调用任意的够赞函数(无参的和有参的).比如:Student student = ne