js对象的创建

//1 新建对象

var box = new Object();
box.name = "lee";
box.age = 100;
box.run = function(){
    return this.name+this.age+"运行中";
}
alert(box.run()); //lee100运行中
//缺点:不能重复,如果再新建一个对象还要写大量重复代码

//2 工厂模式
function box(name,age){
    var obj = new Object();
    obj.name = name;
    obj.age = age;
    obj.run = function(){
        return this.name+this.age+"运行中";
    };
    return obj;   //返回对象
}
var box1 = box("lee",100);
var box2 = box("dang",200);
alert(box1.run());
alert(box2.run());
//缺点:无法搞清实例是哪个对象的实例
alert(typeof box1); //object
alert(box1 instanceof Object);//true,无法识别是哪个对象的实例
alert(box1 instanceof box);  //false,box是function
alert(typeof box);  //function

//3 构造函数创建对象:解决上述问题,不知道是哪个对象的实例
function Box(name,age){  //构造函数名首字母大写(非强制,为了区分),不用返回对象
    this.name = name;
    this.age = age;
    this.run = function(){
        return this.name+this.age+"运行中";
    };
}
var box1 = new Box("lee",100);   //构造函数必须通过new来调用
var box2 = new Box("lee",100);
alert(box1.run());
alert(typeof box1);//object
alert(box1 instanceof Box);  //true,证明是Box的实例
//缺点:引用地址的不一致
alert(box1.name == box2.name);     //true
alert(box1.run() == box2.run());   //true  方法的值一样,因为传参一直
alert(box1.run == box2.run);       //false 方法其实是一种引用地址,
//解决办法:使用了全局的函数run()来解决了保证引用地址一致,单没什么必要,了解就行
//          可以使用原型
function Box(name, age) {
    this.name = name;
    this.age = age;
    this.run = run;
}
function run() {                        //通过外面调用,保证引用地址一致
    return this.name + this.age + ‘运行中...‘;
}

//原型
//4 构造函数创建原型
//我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个对象,它的用途是包含可以由特定类型的所有实例共享的属性和方法。逻辑上可以这么理解:prototype通过调用构造函数而创建的那个对象的原型对象。使用原型的好处可以让所有对象实例共享它所包含的属性和方法。也就是说,不必在构造函数中定义对象信息,而是可以直接将这些信息添加到原型中。
function Box(){}
Box.prototype.name = "lee";
Box.prototype.age = 100;
Box.prototype.run = function(){
    return this.name + this.age + ‘运行中...‘;
}
var box1 = new Box();
var box2 = new Box();
alert(box1.run == box2.run);  //true,方法的引用地址保持一致

alert(Box.prototype.isPrototypeOf(box1));//true,判断一个对象是否指向了该构造函数的原型对象,可以使用isPrototypeOf()方法来测试。

//在原型模式声明中,多了两个属性,这两个属性都是创建对象时自动生成的。__proto__属性是实例指向原型对象的一个指针,它的作用就是指向构造函数的原型属性constructor。通过这两个属性,就可以访问到原型里的属性和方法了。
alert(box1.__proto__); //object,但IE浏览器在脚本访问__proto__会不能识别
alert(box1.constructor); //构造函数的函数体返回

/*
原型模式的执行流程:就近原则
1.先查找构造函数实例里的属性或方法,如果有,立刻返回;
2.如果构造函数实例里没有,则去它的原型对象里找,如果有,就返回;*/
var box = new Box();
alert(box.name);  //lee
box.name = "jack";
alert(box.name);   //jack
delete box.name;
alert(box.name);   //lee,可以删除构造函数里的属性

//如何判断属性是在构造函数的实例里,还是在原型里?可以使用hasOwnProperty()函数来验证
alert(box.hasOwnProperty("name"));  //实例里有true,没有后返回false
//in操作符会在通过对象能够访问给定属性时返回true,无论该属性存在于实例中还是原型中。
alert("name" in box);

//5 为了让属性和方法更好的体现封装的效果,减少不必要的输入,原型的创建可以使用字面量方式
function Box(){};
Box.prototype={
    name:"lee",
    age:100,
    run:function(){
        return this.name + this.age + ‘运行中...‘;
    }
}

//使用构造函数创建原型对象和使用字面量创建对象在使用上基本相同,但还是有一些区别,字面量创建的方式使用constructor属性不会指向实例,而会指向Object,构造函数创建的方式则相反。
alert(box.constructor == Box);                //字面量方式,返回false,否则,true
alert(box.constructor == Object);                //字面量方式,返回true,否则,false
//如果想让字面量方式的constructor指向实例对象,那么可以这么做:
Box.prototype = {
    constructor : Box,                        //直接强制指向即可
};
//PS:字面量方式为什么constructor会指向Object?因为Box.prototype={};这种写法其实就是创建了一个新对象。而每创建一个函数,就会同时创建它prototype,这个对象也会自动获取constructor属性。所以,新对象的constructor重写了Box原来的constructor,因此会指向新对象,那个新对象没有指定构造函数,那么就默认为Object。

//原型的声明是有先后顺序的,所以,重写的原型会切断之前的原型。
function Box() {};

Box.prototype = {                            //原型被重写了
    constructor : Box,
    name : ‘Lee‘,
    age : 100,
    run : function () {
        return this.name + this.age + ‘运行中...‘;
    }
};
Box.prototype = {
    age = 200
};
var box = new Box();                        //在这里声明
alert(box.run());                            //box只是最初声明的原型

//原型对象不仅仅可以在自定义对象的情况下使用,而ECMAScript内置的引用类型都可以使用这种方式,并且内置的引用类型本身也使用了原型。
alert(Array.prototype.sort);                    //sort就是Array类型的原型方法
alert(String.prototype.substring);                //substring就是String类型的原型方法

String.prototype.addstring = function () {        //给String类型添加一个方法
    return this + ‘,被添加了!‘;                //this代表调用的字符串
};

alert(‘Lee‘.addstring());    //使用这个方法
////PS:尽管给原生的内置引用类型添加方法使用起来特别方便,但我们不推荐使用这种方法。因为它可能会导致命名冲突,不利于代码维护。

//原型的缺点:不能传参和共享(共享也是原型的最大优点)

//原型中所有属性是被很多实例共享的,共享对于函数非常合适,对于包含基本值的属性也还可以。但如果属性包含引用类型,就存在一定的问题:
function Box() {};
Box.prototype = {
    constructor : Box,
    name : ‘Lee‘,
    age : 100,
    family : [‘父亲‘, ‘母亲‘, ‘妹妹‘],            //添加了一个数组属性
    run : function () {
        return this.name + this.age + this.family;
    }
};

var box1 = new Box();
box1.family.push(‘哥哥‘);                    //在实例中添加‘哥哥‘
alert(box1.run());

var box2 = new Box();
alert(box2.run());                            //共享带来的麻烦,也有‘哥哥‘了

//6 构造函数+原型模式 为了解决传参和共享的问题
function Box(name,age){
    this.name = name;
    this.age = age;
    this.family = ["baba","mama","meimei"];
};
Box.prototype={
    constructor:Box,
    run:function(){
        return this.name+this.age+this.family;
    }
};
var box1 = new Box();
box1.family.push("gege");
alert(box1.family);
var box2 = new Box();
alert(box2.family);
这种方法解决了传参和引用共享的大难题,是比较好的方法

//7 动态原型模式,相比上边的方法封装性好一点,要注意一点,不可以再使用字面量的方式重写原型,因为会切断实例和新原型之间的联系。
function Box(name,age){
    this.name = name;
    this.age = age;
    this.family = ["baba","mama","meimei"];
    if(typeof this.run != "function"){
        Box.prototype.run = function(){
            return this.name+this.age+"运行中";
        };
    }
}

var box1 = new Box();
box1.family.push("gege");
alert(box1.family);
var box2 = new Box();
alert(box2.family);

//8 如果上述都不能满足条件,可以使用寄生构造函数
//其实就是工厂模式+构造函数模式,比较通用,但不能确定对象关系,所以,在可以使用之前所说的模式时,不建议使用此模式。
function Box(name,age){
    var obj = new Object();
    obj.name = name;
    obj.age = age;
    obj.run = function(){
        return this.name+this.age+"运行中";
    }
    return obj;
}
//在什么情况下使用寄生构造函数比较合适呢?假设要创建一个具有额外方法的引用类型。由于之前说明不建议直接String.prototype.addstring,可以通过寄生构造的方式添加。
function myString(string){
    var str = new String(string);
    str.addstring = function(){
        return this+‘,被添加了!‘;
    };
    return str;
}
var box = new myString("lee");
alert(box.addstring());
//在一些安全的环境中,比如禁止使用this和new,这里的this是构造函数里不使用this,这里的new是在外部实例化构造函数时不使用new。这种创建方式叫做稳妥构造函数。
function Box(name,age){
    var obj = new Object();
    obj.run = function(){
        return name+age+"运行中";
    };
    return obj;
}
var box = Box("lee",100);  //不使用new
alert(box.run());
//稳妥构造函数和寄生相似
时间: 2024-10-11 17:17:44

js对象的创建的相关文章

js对象的创建方式

js对象的创建方式: js也具有OOP编程思想,了解js对象,可以进一步了解js是如何面向对象编程的. js的创建对象方式: 1.   Object var a=new Object();a.name="jack";a.age=20;a.sayName=function () { console.log(this.name);} a.sayName();//打印jack 2.  字面量 var b={name:"rose",age:20,sayName:functi

js:对象的创建(基于组合和动态原型)

基于原型的创建虽然可以有效地完成封装,但是依然存在如下问题: 1.无法通过构造函数来设置属性值 2.当属性中有引用类型变量时,可能存在变量值重复 function Person(){ } Person.prototype = { constructor:Person, name:"Leon", age:30, friends:["Ada","Chris"], say:function(){ alert(this.name+"["

js 对象的创建方式和对象的区别

js一个有三种方法创建对象,这里做一个总结. 1.对象直接量 所谓对象直接量,可以看做是一副映射表,这个方法也是最直接的一个方法,个人比较建议, 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 //创建简单对象 var obj1 = {}; //空对象 var obj2 = {   name: "ys",   age: 12 }; //创建复杂对象 var obj3 = {   name: "ys",   age

js对象的创建模式

方式一: Object构造函数模式 * 套路: 先创建空Object对象, 再动态添加属性/方法 * 适用场景: 起始时不确定对象内部数据 * 问题: 语句太多 /* 一个人: name:"Tom", age: 12 */ // 先创建空Object对象 var p = new Object() p = {} //此时内部数据是不确定的 // 再动态添加属性/方法 p.name = 'Tom' p.age = 12 p.setName = function (name) { this.

JS对象的创建与使用

本文内容: 1.介绍对象的两种类型: 2.创建对象并添加成员: 3.访问对象属性: 4.利用for循环枚举对象的属性类型: 5.利用关键字delete删除对象成员 6.作为函数参数的对象: ★JavaScript对象有两种类型     1.Native:在ECMAScript标准中定义和描述,包括JavaScript内置对象(数组,日期对象等)和用户自定义对象: 2.Host:在主机环境(如浏览器)中实现并提供给开发者使用,比如Windows对象和所有的DOM对象: ★ 创建对象:定义空对象之后

JS对象与PHP对象的对比

一.对象的创建与访问 1.JS对象的创建与访问 //方式一(通过内置构造函数创建后添加属性) var obj = new Object(); obj.name = 'Lucy'; //通过点添加属性 obj['sex'] = 'female'; //通过[]添加属性 //方式二(通过json格式直接创建添加属性) var obj = {'name':'lily','sex':'female'}; //js对象可通过'.'和'[]'访问属性 console.log(obj.name); conso

浅谈Js对象的概念、创建、调用、删除、修改!

一.我们经常困惑,对象究竟是什么,其实这是一种思维,一种意识上的东西,就像我们都说    世界是有物质组成的道理一样,理解了下面的几句话!对象也不是那么抽象!    1.javascript中的所有事物都是对象,字符串.数值.数组.函数!    而且js还允许自定义对象!    2.对象就只是带有属性和方法的特殊数据类型    3.属性是与对象相关的值,方法是能够在对象上执行的动作! 其实在这里的时候我们应该就有一个疑问要解决了,我们说函数是一个对象,为什么?    很简单,js中所有的事物都是

创建Vue.js对象:我的第一个Vue.js输出信息

<!DOCTYPE html><html><head><meta charset=”utf-8″><title>Vue第一条信息</title><script src=”js/vue.js”></script></head><body><div id=”app”><p>{{ message }}</p></div> <script&g

js:对象的创建(为prototype做铺垫)

/** *在js中并不存在类,所以可以直接通过Object来创建对象,但是使用这种方式创建有一 *弊端:由于没有类的约束,无法实现对象的重复利用,并且没有一种规范约定,在操作时容易带来问题. */ var person = new Object(); person.name = "octopus"; person.age = 25; person.say = function(){ alert(this.name+","+this.age); } json:json