//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());
//稳妥构造函数和寄生相似

js对象的创建与原型总结的更多相关文章

  1. js对象的创建

    一.通过对象直接量来创建 var emptyt={};  //相当于var empty=new Object; //如果属性名中包含空格.连字符(-).还有关键字,保留字时,要用字符串表示 var b ...

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

    js一个有三种方法创建对象,这里做一个总结. 1.对象直接量 所谓对象直接量,可以看做是一副映射表,这个方法也是最直接的一个方法,个人比较建议, 1 2 3 4 5 6 7 8 9 10 11 12 ...

  3. js对象的创建模式

    方式一: Object构造函数模式 * 套路: 先创建空Object对象, 再动态添加属性/方法 * 适用场景: 起始时不确定对象内部数据 * 问题: 语句太多 /* 一个人: name:" ...

  4. JS 对象API之获取原型对象

    1.从 构造函数 获得 原型对象: 构造函数.prototype 2.从 对象实例 获得 父级原型对象: 方法一: 对象实例.__proto__        [ 有兼容性问题,不建议使用] 方法二: ...

  5. JS对象中,在原型链上找到属性后 最终将值拷贝给原对象 而不是引用

    遇到一个面试题 要求写一个函数A,每次进行new操作时候能输出2,3,4,5... new A() // 输出2 new A() // 输出3 new A() // 输出4 function A() ...

  6. JS对象的创建与使用

    本文内容:     1.介绍对象的两种类型:     2.创建对象并添加成员:     3.访问对象属性:     4.利用for循环枚举对象的属性类型:     5.利用关键字delete删除对象成 ...

  7. js对象的几种创建方式和js实现继承的方式[转]

    一.js对象的创建方式 1. 使用Object构造函数来创建一个对象,下面代码创建了一个person对象,并用两种方式打印出了Name的属性值. var person = new Object(); ...

  8. javascript基础-js对象

    一.js对象的创建 1.普通最简单的方式 var teacher = new Object( ); teacher.name = "zhangsan"; teacher.age = ...

  9. 探讨一下js中的继承和原型链

    ---恢复内容开始--- 每个JS对象一定对应一个原型对象,并从原型对象继承属性和方法. 也就是说 对象的__proto__属性的值就是它所对应的原型对象, 而prototype 只有函数才有的属性. ...

随机推荐

  1. Dijkstra(歪果仁的名字真是长。。。)

    Dijkstra算法又称为单源最短路径,所谓单源是在一个有向图中,从一个顶点出发,求该顶点至所有可到达顶点的最短路径问题.       设G=(V,E)是一个有向图,V表示顶点,E表示边.它的每一条边 ...

  2. 剑指Offer 整数中1出现的次数(从1到n整数中1出现的次数)

    题目描述 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次,但是对于后面问题他就没辙了. ...

  3. C++ const用法 尽可能使用const [转载]

    C++ const 允许指定一个语义约束,编译器会强制实施这个约束,允许程序员告诉编译器某值是保持不变的.如果在编程中确实有某个值保持不变,就应该明确使用const,这样可以获得编译器的帮助. 1.c ...

  4. 高性能图片服务器–ZIMG

    2011年李彦宏在百度联盟峰会上就提到过互联网的读图时代已经到来1,图片服务早已成为一个互联网应用中占比很大的部分,对图片的处理能力也相应地变成企业和开发者的一项基本技能.需要处理海量图片的典型应用有 ...

  5. 这些情况下onReume不应该是你的选择

    面试Android程序员的时候问过以下几个基本问题,得到的回答经常不尽人意: 1, Activity A跳转到Activity B,Activity B完成后,Activity A要刷新一下自己的数据 ...

  6. BSON 1.0版本规范(翻译)

    BSON 1.0版本规范 本文翻译自 http://bsonspec.org/spec.html BSON是用于存储零个或多个键/值对为一个单一的实体的一个二进制格式.我们称这个实体为文档(Docum ...

  7. Tomcat异常 Multiple Contexts have a path of "/qqshl".解决方法

    Tomcat异常 Multiple Contexts have a path of "/qqshl".解决方法 找到tomcat映射文件Service.xml,将文件中的conte ...

  8. OLA音频变速算法的仿真与剖析

    前段时间,在尝试音乐节拍数的提取时,终于有了突破性的进展,效果基本上比市面上的许多商业软件还要好,在作节拍数检测时,高频信息作用不大, 通过重采样减小运算量.重采样让我想起了在学校里面做的变速变调算法 ...

  9. ITIL与ITSM的联系与区别

    1.ITIL(IT Infrastructure Library)是CCTA(英国国家计算机和电信局)于20世纪80年代末开发的一套IT服务管理标准库,它把英国各个行业在IT管理方面的最佳实践归纳起来 ...

  10. Hadoop2.2.0环境下Sqoop1.99.3安装

    本文转载自http://blog.csdn.net/liuwenbo0920/article/details/40504045 1.安装准备工作: 已经装好的hadoop环境是hadoop 2.2.0 ...