JS对象

创建一个对象两种基本方式
第一种方式,创建一个object实例

var newobject = new Object();
newobject.name = "w";
newobject.age = 22;
newobject.job = "engineer";
newobject.sayName = function() {
    alert(this.name);
};

第二种方式,使用字面量的方式

var newobject = {
    name:"w",
    age:22,
    job:"engineer",

    sayname:function(){
        alert(this.name);
    }
};

数据属性
修改属性的特性可以使用es5定义的Object.defineProperty(),接受三个参数,属性所在的对象,属性的名字和一个描述符对象。描述符对象的属性, configureable, enumerable,writeable,value。。。。
[[configureable]] 能否通过delete删除属性而重新定义属性,默认为true
访问器属性
configureable, enumerable,get,set

几种创建对象的模式
1,工厂模式

//工厂模式
function createobject(name,age,job){
    var obj = new Object();
    obj.name = name;
    obj.age = age;
    obj.job = job;
    obj.sayname = function(){
        alert(this.name);
    };
    return obj;
}
var newobj = createobject("w",18,"engineer");
newobj.sayname();

解决了创建多个相似对象的问题,不能解决对象识别问题(怎样知道一个对象的类型)
2,构造函数模式

//构造函数模式
function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function(){
        alert(this.name);
    };
}
var ww = new Person("w",19,"haha");
alert(ww.name);

使用构造函数模式会经历大概四个步骤:
1)、创建一个新对象
2)、将构造函数作用域传给新对象(使用this指向了新对象)
3)、执行构造函数中的代码(添加属性和方法)
4)、返回新的对象

alert(ww.constructor==Person);//ww对象有个constructor构造函数属性,指向Person,返回true

对于构造函数,任何函数只要是可以用new操作符调用,都可以作为构造函数,如果不用new操作符调用则和普通函数没有什么差别。
构造函数的问题在于每个方法都要在实例上重新创建一遍,会导致不同的作用域链和标识符解析

var w1 = new Person("w1",19,"h1");
var w2 = new Person("w2",19,"h2");
//w1和w2 都有sayName的方法,但是不是同一个Function实例

我们可以把方法的定义放在构造函数之外,但是如果涉及到很多方法,就意味着需要在外面定义许多函数,这个显然是不科学的
3,原型模式
每一个函数都有一个prototype(原型)属性,是一个指针,指向一个对象,这个对象的用途是可以包含由特定类型的所有共享实例的属性和方法。prototype就是可以通过调用构造函数而创建那个对象实例的原型对象。。。。。
好处是可以让所有对象实例共享原型对象所包含的属性和方法,不必再构造函数中定义实例对象的信息,可以将这些信息直接添加到原型对象中。

//原型模式
function Person(){
}
Person.prototype.name = "ww";
Person.prototype.age = 19;
Person.prototype.job = "ha";
Person.prototype.sayName = function(){
    alert(this.name);
};
var w1 = new Person();
var w2 = new Person();
alert(w1.sayName()==w2.sayName());//true
//属性和方法是所有实例共享的 

原型对象:只要创建了一个新的函数,就会根据特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。默认情况下,所有的原型对象会自动获得一个constructor属性,这个属性包含一个指向prototype属性所在函数的指针。
原型对象除了构造函数属性之外,还包括后面添加的其他属性。

alert(Person.prototype.isPrototypeOf(w1)); 
//true   内部有指向Person.prototype的指针
alert(Object.getPrototypeOf(w1)==Person.prototype);//true

可以通过实例对象访问原型对象中的值,但是却不能更改它的值。
为实例对象添加一个属性时,会屏蔽掉原型对象中同名属性,只会阻止我们访问原型对象中的属性却不能修改那个属性。可以使用delete操作符删除实例对象添加的属性。
hasOwnProperty(),检测属性是存在实例对象中还是原型对象中。

w1.name = "w1";
w1.sayName();//w1
alert(w1.hasOwnProperty("name"));//属性存在实例对象中返回true
delete w1.name;//删除了实例对象添加的属性
w1.sayName();//ww
alert(w1.hasOwnProperty("name"));//false

可以使用in操作符判断属性是否存在对象中。

可以使用对象字面量方式写原型对象:

Person.prototype = {
    name:"ww",
    age:19,
    job:"ha",
    sayName:function(){
        alert(this.name);
    }
};

但是constructor不再指向Person。

alert(w1.constructor == Person);//false

可以重新将constructor写为Person。

Person.prototype = {
    constructor:Person,
    name:"ww",
    age:19,
    job:"ha",
    sayName:function(){
        alert(this.name);
    }
};
var w1 = new Person();
w1.sayName();
alert(w1.constructor == Person);//true

原型模式的问题在于,所有实例默认情况下都取得相同的属性值。
4,组合使用构造函数模式和原型模式
构造函数模式用于定义实例属性,原型模式用于定于方法和共享的属性。

//组合使用构造函数模式和原型模式
function Person(name,age){
    this.name = name;
    this.age = age;
    this.friends = ["1","2"];
}
Person.prototype = {
    constructor:Person,
    sayName:function(){
        alert(this.name);
    }
}
var w1 = new Person("w1",19);
var w2 = new Person("w2",18);
w1.friends.push("3");
alert(w1.friends);
alert(w2.friends);
alert(w1.friends == w2.friends);//false

这种模式很好理解。对其中一个实例对象的属性值修改时,其他实例不受影响。
5,动态原型模式

function Person(name, age) {
    this.name = name;
    this.age = age;
    if(typeof this.sayName != "function") {
        //不存在sayName方法才会创建该方法
        //对原型对象的修改会在所有实例的立即反应出来
        Person.prototype.sayName = function() {
            alert(this.name);
        };
    }
}
var w1 = new Person("w1",19);
w1.sayName();

6,寄生构造函数模式

//寄生构造函数模式
function createobject(name,age,job){
    var obj = new Object();
    obj.name = name;
    obj.age = age;
    obj.job = job;
    obj.sayname = function(){
        alert(this.name);
    };
    return obj;
}
var newobj = new createobject("w",18,"engineer");
newobj.sayname();

和工厂模式有些略微的不同
7,稳妥构造函数模式
稳妥对象是指没有公共属性,方法也不引用this的对象。

//稳妥对象模式
function createobject(name,age,job){
    //没有别的方法能访问到传入构造函数的原始数据
    var obj = new Object();
    //添加私有变量和函数
    obj.sayname = function(){
        //除了这个方法没有其他方法能访问到name
        alert(name);
    };
    return obj;
}
var w = createobject("w",20,"no");
w.sayname();

或许自己的理解还不够深刻,主要是总结书上的内容,写在这里方便以后查阅,请大家多多指教。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值