对象创建

1.工厂模式

优点:解决了创建多个相似对象的问题

缺点:没有解决对象识别问题;每一个对象都有一套自己的函数,浪费资源

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"); person1.sayName(); //"Nicholas"
person2.sayName(); //"Greg"

2.构造函数模式

优点:可以用来创建特定类型的对象

缺点:每个方法都要在每个实例上重新创建一遍

function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
};
} /////////////////////////////////////////////////////////////
var person1 = new Person("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");

3.原型模式

优点:所有对象实例可以共享它所包含的属性和方法

缺点:共享性,所有的均共享,对龚鸥的固然很好,但不能私有各自属性了

// 写法1:
function Person() {}
Person.prototype = {
constructor: Person,
name: "Nicholas",
age: 29,
job: "Software Engineer",
sayName: function() {
alert(this.name);
}
} // 写法2:
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

4.构造函数模式和原型模式

思路:构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性

优点:每个实例都会有自己的一份实例属性副本,但同时又共享着对方法的引用,最大限度的节省了内存

缺点

关于constructor的补充知识点:

  1. 只要创建了一个新函数,就会根据一组特定的规则为这个函数创建一个prototype属性,这个属性指向函数的原型对象。
  2. 在默认情况下,所有原型对象都会自动获得一个constructor构造函数属性,这个属性会包含一个指向protoype属性所在函数的指针。
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,Count,Van"
alert(person2.friends); //"Shelby,Count"
alert(person1.friends === person2.friends); //false
alert(person1.sayName === person2.sayName); //true

5.动态原型模式

思路:和4相比只是多了一个函数存在的检测

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

6.寄生构造函数模式

从表面上看是和工厂模式一样,只是最后实例化了一次,而工厂模式是没有再实例化

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

7.稳妥构造函数模式

所谓稳妥对象,指的是没有公共属性,而且其方法也不引用this的对象。稳妥构造函数遵循与寄生构造函数类似的模式,有两点不同:

1.新创建对象的实例方法不引用this

2.不使用new操作符调用构造函数

function Person(name,age,job){
//创建要返回的对象
var o = new Object();
// 可以在这里定义私有变量和函数
//添加方法
o.sayName = function(){
alert(name);
}
return o;
} /////////////////////////////////////////////////////////
var friend = Person("Nicholas",29,"Software Engineer");
friend.sayName(); // Nicholas

继承

1.原型链继承

思路:用父类实例来充当子类实例对象

缺点

1.共享(包含引用类型值的原型属性会被所有实例共享)

2.不能传参(没有办法在不影响对象实例的情况下给超类型的构造函数传递参数)

function SuperType() {  // 定义父函数
this.property = true;
}; SuperType.prototype.getSuperValue = function() { // 给父函数添加方法
return this.property;
}; function SubType() { // 定义子函数
this.subproperty = false;
}; SubType.prototype.getSubValue = function() { // 给子函数添加方法
return this.subproperty;
}; /////////////////////////////////////
SubType.prototype = new SuperType(); // (关键) var instance = new SubType(); // 实例化instance
alert(instance.getSuperValue()); //true

2.借用构造函数

思路:借父类的构造函数来增强子类实例(等于把父类的实例属性复制了一份给子类实例装上了)

优点:可传参(可以在子类型的构造函数向超类型的构造函数传递参数)

缺点:不能复用(超类型原型链中定义的方法对子类是不可见的)

function SuperType() {  // 定义父函数
this.colors = ["red", "blue", "green"];
} function SubType() { // 定义子函数
SuperType.call(this); // (关键)
} /////////////////////////////////////////////////
var instance1 = new SubType();
instance1.colors.push("black");
alert(instance1.colors); // "red,blue,green,black"
var instance2 = new SubType();
alert(instance2.colors); // "red,blue,green"

3.组合继承

思路:把实例函数放在原型对象上,以实现函数复用

优点:无共享问题,可传参,可复用

缺点:父类构造函数会被调用两次,生成两份,而子类实例上的那一份屏蔽了子类原型上的,内存浪费。

function SuperType(name) {  // 定义父函数
this.name = name;
this.colors = ["red", "blue", "green"];
} SuperType.prototype.sayName = function() { // 给父函数添加方法
alert(this.name);
}; function SubType(name, age) { // 定义子函数
//继承属性
SuperType.call(this, name); // (关键:继承私有属性)
this.age = age;
} //继承方法
SubType.prototype = new SuperType(); // (关键:继承公有方法)
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function() {
alert(this.age);
}; ///////////////////////////////////////////////////
var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
alert(instance1.colors); // "red,blue,green,black"
instance1.sayName(); // "Nicholas";
instance1.sayAge(); // 29
var instance2 = new SubType("Greg", 27);
alert(instance2.colors); // "red,blue,green"
instance2.sayName(); // "Greg";
instance2.sayAge(); // 27

4.原型式继承

思路:用Object函数得到一个空的新对象,再逐步增强填充实例属性

优点:从已有的对象上衍生新对象,不需要创建自定义类型

缺点:共享问题

Object.create() :ES5中规范了原型式继承

参数1:用作新对象原型的对象

参数2:为新对象定义额外属性的对象

function object(o){
function F(){}
F.prototype = o;
return new F();
} var person = { // 父函数
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
}; var anotherPerson = object(person); // (关键)子1继承父
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob"); var yetAnotherPerson = object(person); // (关键)子2继承父
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie"); alert(person.friends); //"Shelby,Court,Van,Rob,Barbie"

5.寄生式继承

思路:创建一个用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后返回

优点:不需要创建自定义类型

缺点:不能复用

function createAnother(original) {
var clone = object(original); //通过调用函数创建一个新对象
clone.sayHi = function(){ //以某种方式来增强这个对象
alert("hi");
};
return clone; //返回这个对象
} var person = { // 父函数
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
}; var anotherPerson = createAnother(person); // (关键)子函数继承父函数
anotherPerson.sayHi(); //"hi"

6.寄生组合式

思路:切掉了原型对象上多余的那份父类实例属性

function inheritPrototype(subType, superType) {
var prototype = object(superType.prototype); //创建对象
prototype.constructor = subType; //增强对象
subType.prototype = prototype; //指定对象
} function SuperType(name) {
this.name = name;
this.colors = ["red", "blue", "green"];
} SuperType.prototype.sayName = function() {
alert(this.name);
};
function SubType(name, age) {
SuperType.call(this, name); // (关键)
this.age = age;
}
inheritPrototype(SubType, SuperType); // (关键)
SubType.prototype.sayAge = function() {
alert(this.age);
};

js中的对象创建与继承的更多相关文章

  1. javascript中的对象创建与继承

    js是一门基于原型的面向对象语言,与传统的面向对象如Java,C#相比,它在对象创建及继承上有自己独特的实现方式,本文主要描述js中对象创建及继承的一些实践. 1.对象创建 方式一:工厂模式创建对象 ...

  2. js中函数对象创建的总结

    在JavaScript的函数对象创建方法中,可以分为三种情况: 1:第一种是使用function语句定义函数 <script type="text/javascript"&g ...

  3. JS中有关对象的继承以及实例化、浅拷贝深拷贝的奥秘

    一.属性的归属问题 JS对象中定义的属性和方法如果不是挂在原型链上的方法和属性(直接通过如类似x的方式进行定义)都只是在该对象上,对原型链上的没有影响.对于所有实例共用的方法可直接定义在原型链上这样实 ...

  4. 浅解析js中的对象

    浅解析js中的对象 原文网址:http://www.cnblogs.com/foodoir/p/5971686.html,转载请注明出处. 前面的话: 说到对象,我首先想到的是每到过年过节见长辈的时候 ...

  5. JavaScript学习12 JS中定义对象的几种方式【转】

    avaScript学习12 JS中定义对象的几种方式 转自:  http://www.cnblogs.com/mengdd/p/3697255.html JavaScript中没有类的概念,只有对象. ...

  6. javascript对象创建及继承

    //****************************************************************************** //创建类的多种方式 //------ ...

  7. 深入理解JS中的对象(一)

    目录 一切皆是对象吗? 对象 原型与原型链 构造函数 参考 1.一切皆是对象吗? 首先,"在 JavaScript 中,一切皆是对象"这种表述是不完全正确的. JavaScript ...

  8. 深入理解JS中的对象(三):class 的工作原理

    目录 序言 class 是一个特殊的函数 class 的工作原理 class 继承的原型链关系 参考 1.序言 ECMAScript 2015(ES6) 中引入的 JavaScript 类实质上是 J ...

  9. JS中通过call方法实现继承

    原文:JS中通过call方法实现继承 讲解都写在注释里面了,有不对的地方请拍砖,谢谢! <html xmlns="http://www.w3.org/1999/xhtml"& ...

随机推荐

  1. linux设备驱动程序--类class的实现

    #include <linux/module.h> #include <linux/fs.h> #include <linux/sched.h> #include ...

  2. 复位windows网络参数的方法

    使用电脑的时候,经常会遇到网络相关的问题,以前读大学的时候就知道怎么解决,就是下面这个方案. 开始-全部程序-附件-命令提示符-右键-以管理员身份运行出来一个黑底白字的窗口,在里面输入: netsh ...

  3. 终结python协程----从yield到actor模型的实现

    把应用程序的代码分为多个代码块,正常情况代码自上而下顺序执行.如果代码块A运行过程中,能够切换执行代码块B,又能够从代码块B再切换回去继续执行代码块A,这就实现了协程 我们知道线程的调度(线程上下文切 ...

  4. Objective-C 空指针和野指针

    一.什么是空指针和野指针 1.空指针 1> 没有存储任何内存地址的指针就称为空指针(NULL指针) 2> 空指针就是被赋值为0的指针,在没有被具体初始化之前,其值为0. 下面两个都是空指针 ...

  5. java泛型应用实例 - 自定义泛型类,方法

    近 短时间需要使用泛型,就研究了下,发现网上的问关于泛型的文章都是讲原理的, 很少有提到那里用泛型比较合适, 本文就泛型类和泛型方法的使用给出两 个典型应用场景. 例如一个toString的泛型方法, ...

  6. Centos 如何 发布Java项目

    在发布Java项目之前,我们先要安装如下软件 一.Windows 1.winscp(Windows到centos上传下载) 2.PuTTY(Windows访问centos服务器) 3.Navicat客 ...

  7. 阿里云服务器连接邮箱SMTP服务器time out的解决

    给官方提了个工单,回复如下: 去年9月底开始,出于上级对垃圾邮件管控的要求,新购VPC服务器限制了25端口,我们建议您使用邮件服务商的加密465端口. 或者您查询下所希望访问的发信服务是否提供了像阿里 ...

  8. Error:unsupported class file version 52.0问题的解决

    这个问题主要的原因是依赖包的编译版本比主程序的编译版本高,导致主程序无法正常编译或运行,解决这个问题无非两招: 1.提升主程序的编译器版本,用最新的编译器编译主程序,这样就可以兼容那个依赖包 2.降低 ...

  9. Vue、AngularJS 双向数据绑定解剖

    数据与视图的绑定与同步,最终体现在对数据的读写处理过程中,也就是 Object.defineProperty() 定义的数据 set.get 函数中.Vue 中对于的函数为 defineReactiv ...

  10. java之Spring(AOP)-Annotation实现添加切面

    我们已经知道之前的切面添加方式(动态代理),是定义了一个实现了InvocationHandler接口的Handlerservice类,然后 在这个类内部写好切面逻辑,包括切面放置的位置,很显然下面的这 ...