资讯专栏INFORMATION COLUMN

Javascript的对象创建方法

ZoomQuiet / 1326人阅读

摘要:构造函数与原型组合利用构造函数都是实例属性和原型的共享特性,分别定义对应的内容,组合共同完成对象创建,而且该模式还支持想构造函数传递参数。引用类型为实例属性寄生构造模式构造函数在不反回值的情况下,默认会返回新对象实例。

创建对象 1.1 通过Object对象创建
var person = new Object();
person.name = "Albert";
person.sayName = function(){
    console.log(this.name);
};
1.2 通过字面量创建
var person = {
    name : "Albert",
    sayName : function(){
        console.log(this.name)
    }
};
Object和字面量创建的问题:

创建很多对象的时候会产生大量重复代码。

1.3 工厂模式
function createPerson(name){
    var o = new Object();
    o.name = name;
    o.sayName = function(){
        console.log(this.name)
    }
    return o;
}
var person = createPerson("Albert");
工厂模式的问题:

无法识别对象类型,即无法通过instanceofconstructor来识别对象类型:

person instanceof ???;
person.constructor == ???;
1.4 构造函数
function Person(name){
    this.name = name;
    this.sayName = function(){
        console.log(this.name)
    }
}
var person = new Person("Albert");
console.log(person.constructor == Person)//true
console.log(person instanceof Person)//true
构造函数的问题:

每个方法都要在每个实例上重新创建一次,尤其是函数,这样每个Person的实例都包含了一个不同的sayName的函数实例。

注意1
构造函数没有return语句。要创建Person的新实例,必须采用new操作符,new操作符大体上完成了一下4件事情:

创建一个新的对象(本例中Person创建的新对象,记为person);

将构造函数的作用域赋给新对象(this=>person);

执行构造函数中的代码(Person中的this.name=name;this.say.....);

返回新对象

注意2
构造函数也是函数,如果不通过new操作符调用,则作用环境为全局(浏览器中为windows,node环境中为global

function Person(name){
    this.name = name;
    this.sayName = function(){
        console.log(this.name)
    }
}

Person("BB");
global.sayName()//BB
console.log(global.name)//BB
1.5 原型模式
function Person(name){}
Person.prototype.name = "Albert";
Person.prototype.sayName = function(){
        console.log(this.name)
    }

var person = new Person();
console.log(Object.getPrototypeOf(person)==Person.prototype);//true

浏览器支持:IE9+,这样所有的Person实例共享name属性及sayName函数

注意1

对象的某个属性是否来自实例,可通过hasOwnProperty()来确定,如果是在原型中,则返回false

判断对象是否具备属性,可以通过in操作符,例如console.log("name" in person)//true来判断,不论是在原型还是实例中,都返回true,通过for-in循环时,实例及原型中均会被枚举。

注意2
在定义原型时,如果用字面量代替为prototype属性定义,则原型的constructor属性不会指向Person。因为通过字面量定义,完全重写了默认的prototype对象。但是此时instanceof还是能够返回正确的结果。

function Person(name){};
Person.prototype={
    name : "Albert",
    sayName : function(){
        console.log(this.name);
    }
};
var person = new Person();
console.log(person instanceof Person);//true
console.log(person.constructor == Person);//false
console.log(person.constructor == Object);//true

所以可以再补充定义:

Object.defineProperty(Person.prototype,"constructor",{
    enumerable:false,
    value:Person
})

注意3
在重定义原型前,不能创建对象实例,否则会造成实例的原型指向错误

function Person(name){};
var person = new Person();
Person.prototype={
    name : "Albert",
    sayName : function(){
        console.log(this.name);
    }
};
person.sayName(); //error

此例中person的原型被指向了Person的默认原型,固调用sayName函数会发生错误。

原型模式的问题:

小问题:为了省略构造函数传递初始化参数,所有的实例在默认情况下都会去的想通的属性值

原型属性被所有实例共享(适合function类型的值),而通常情况下,引用类型(ArrayObject)属性值一般不希望对所有实例共享。

1.6 构造函数与原型组合

利用构造函数都是实例属性和原型的共享特性,分别定义对应的内容,组合共同完成对象创建,而且该模式还支持想构造函数传递参数。

function Person(name){
    this.name = name;
    this.friends = ["Bob","Harry"];//引用类型为实例属性
};
Person.prototype.sayName = function(){
        console.log(this.name);
};
1.7 动态原型模式

将1.6中的组合封装在一个构造函数中的模式。具体方法为:检查某个应该存在的方法是否有效来决定是否需要初始化原型。

function Person(name){
    this.name = name;
    this.friends = ["Bob","Harry"];//引用类型为实例属性
    //****ProtoType****
    if(typeof this.sayName != "function"){
        Person.prototype.sayName = function(){
            console.log(this.name);
        };
    }
};
1.8 寄生构造模式

构造函数在不反回值的情况下,默认会返回新对象实例。
而通过在函数末尾添加return语句,可以重写new后调用函数时的返回值。

function Person(name){
    var o = new Object();
    o.name = name;
    o.sayName = function(){
        console.log(this.name);
    };
    return o;
};
var person = new Person("Albert");
console.log(person instanceof Person);//false

该函数除了使用new操作符和把包装函数取名叫“构造函数”以外,和工厂模式其实是一模一样的。
该模式属于比较特殊的构造模式,可用于不允许修改原对象的情况。

function SpecialArray(){
    var values = new Array();
    values.push.apply(values,arguments);
    values.toPipedString = function(){
        return this.join("|");
    };
    return values
}
1.9 稳妥(durable)构造函数模式

该模式构造出来的对象没有公共属性,不适用this对象,不适用new操作符,适用于在一些安全环境中,可防止数据被其它应用(如Mashup)改动(利用闭包特性),类似于寄生构造函数模式,单不适用thisnew

function Person(name){
    var o = new Object();
    //****定义私有变量和函数****
    var _name = name;
    o.sayName = function(){
        console.log(_name);
    };    
    return o;
};
var person = Person("Albert");

这种模式中,除了sayName()方法以外,没有其它办法访问_name的值。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/86914.html

相关文章

  • JavaScript对象

    摘要:对象的分类内置对象原生对象就是语言预定义的对象,在标准定义,有解释器引擎提供具体实现宿主对象指的是运行环境提供的对象。不过类型是中所有类型的父级所有类型的对象都可以使用的属性和方法,可以通过的构造函数来创建自定义对象。 对象 javaScript中的对象,和其它编程语言中的对象一样,可以比照现实生活中的对象来理解。在JavaScript中,一个对象可以是一个单独拥有属性和类型的实体。和...

    xavier 评论0 收藏0
  • JavaScript...对象...

    摘要:对象对象是什么中的对象和其他编程语言中的对象一样可以比照现实上活中的对象来理解它中对象的概念可以比照现实生活中实实在在的物体来理解在中一个对象可以是一个单独的拥有属性和类型的实体拿它和一个杯子做下类比一个杯子是一个对象拥有属性杯子有颜色图案 对象 对象是什么 JavaScript中的对象 和其他编程语言中的对象一样 可以比照现实上活中的对象来理解它JavaScript中对象的概念可以比...

    xuxueli 评论0 收藏0
  • JavaScript核心语法——对象

    摘要:张无忌对象的属性存在对象的属性不存在使用进行判断。张无忌对象的属性存在请先定义对象的属性使用语句进行判断张无忌对象的属性存在删除对象的属性可以用操作符删除一个不是继承而来的属性。 对象 对象的概述 对象是什么 JavaScript中的对象,和其他编程语言中的对象一样。可以对比现实生活中的一些东西来理解他。在JavaScript中,一个对象可以使一个单纯的拥有属性和类型的实体。假如和一个...

    philadelphia 评论0 收藏0
  • JavaScript 闯关记》之对象

    摘要:属性名可以是包含空字符串在内的任意字符串,但对象中不能存在两个同名的属性。客户端中表示网页结构的对象均是宿主对象。这里的函数称做构造函数,构造函数用以初始化一个新创建的对象。通过关键字和构造函数调用创建的对象的原型就是构造函数的属性的值。 对象是 JavaScript 的数据类型。它将很多值(原始值或者其他对象)聚合在一起,可通过名字访问这些值,因此我们可以把它看成是从字符串到值的映射...

    rozbo 评论0 收藏0
  • JavaScript面向对象OOM 2(JavaScript 创建对象工厂模式和构造函数模式)

    摘要:都是构造函数模式创建的原生构造函数。使用构造函数创建对象经历了以下四个过程创建一个新对象构造函数的作用域交给新对象。   在创建对象的时候,使用对象字面量和 new Object() 构造函数的方式创建一个对象是最简单最方便的方式。但是凡是处于初级阶段的事物都会不可避免的存在一个问题,没有普适性,意思就是说我要为世界上(程序中)的所有使用到的对象都使用一遍 var xxx = {} ,...

    you_De 评论0 收藏0
  • JavaScript面向对象OOM 2(JavaScript 创建对象工厂模式和构造函数模式)

    摘要:都是构造函数模式创建的原生构造函数。使用构造函数创建对象经历了以下四个过程创建一个新对象构造函数的作用域交给新对象。   在创建对象的时候,使用对象字面量和 new Object() 构造函数的方式创建一个对象是最简单最方便的方式。但是凡是处于初级阶段的事物都会不可避免的存在一个问题,没有普适性,意思就是说我要为世界上(程序中)的所有使用到的对象都使用一遍 var xxx = {} ,...

    liuchengxu 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<