资讯专栏INFORMATION COLUMN

js面向对象

LeviDing / 2886人阅读

摘要:创建对象的方法字面量优点简单方便缺点每创建一个对象都要重新写,且创建多个比较占内存工厂模式优点改善了字面量方法创建多个相似对象的问题,不需要编写重复的代码缺点没有解决对象是别的问题,不知道对象的类型是什么构造函数模式优点创建并定义了对象类型

创建对象的方法

1.字面量

// 优点:简单方便
// 缺点:每创建一个对象都要重新写,且创建多个比较占内存
var obj1 = {
    name: "liuhui1"
};
var obj2 = new Object({
    name: "liuhui2"
});
var obj3 = Object.create({
    name: "liuhui3"
});

2.工厂模式

// 优点:改善了字面量方法创建多个相似对象的问题,不需要编写重复的代码
// 缺点:没有解决对象是别的问题,不知道对象的类型是什么
function person () {
    var obj = new Object();
    obj.name = "liuhui4";
    obj.sayName = function () {
      console.log(this.name);
    };
    return obj;
}
var obj4 = person();
console.log(obj4.sayName());

3.构造函数模式

// 优点:创建并定义了对象类型的属性和方法,可以标示为特定的类型(自定义构造函数,原生:Object/Array)
// 缺点:方法没有被共享,每次实例一个对象都要重复绑定一个独立的方法
function Person (name) {
    this.name = name;
    this.sayName = function () {
        console.log(this.name);
    };
    this.newFun = newFun;
}
// 解决办法:将方法写在全局,但是就变成全局方法了跟封装的观念相违背了
// 新增代码
function newFun () {
    console.log("new name: " + this.name);
}
var obj5 = new Person("liuhui5");
console.log(obj5.sayName());

4.原型模式

// 优点:将方法封装到相应的原型对象上,私有并实例可以共享这些属性和方法
// 缺点:所有属性和方法都共享了,改变实例的属性和方法会影响原型对象上的属性和方法
function Person1 () {

}
Person1.prototype = {
    constructor: Person1,
    name: "liuhui6",
    sayName: function () {
        console.log(this.name);
    }
};
var obj6 = new Person1();
console.log(obj6.sayName());

5.组合模式(构造函数+原型模式)还没有完全理解

// 优点:构造函数用于定义实例属性和方法,原型模式用于共享定义的属性和方法
function Person2 (name) {
    this.newName = function () {
        console.log(name);
    }
}
Person2.prototype = {
    constructor: Person2,
    name: "liuhui7",
    sayName: function () {
        console.log(this.name);
    }
};
var obj7 = new Person2();
var obj8 = new Person2("liuhui8");
继承的方法

1.借助构造函数实现继承

// 缺点:父级构造函数属性和方法没有被共享
function Parent1 () {
    this.name = "parent1";
    this.play = [1, 2, 3];
}
function Child1 () {
    Parent1.call(this); // 关键:执行父级构造函数,深复制
    this.type = "child1";
}
Parent1.prototype.say = function () {
    console.log("hello1");
};
console.log(new Child1());
var s1 = new Child1();
var s2 = new Child1();
s1.play.push(4);
console.log(s1.play, s2.play, s1.hasOwnProperty("play"), "test1");

2.借助原型链实现继承

// 缺点:原型链上的属性和方法是共享
function Parent2 () {
    this.name = "parent2";
    this.play = [1, 2, 3];
}
function Child2 () {
    this.type = "child";
}
Parent2.prototype.say = function () {
    console.log("hello2");
};
Child2.prototype = new Parent2(); // 关键:将子级执行父级构造函数实现继承,浅复制
console.log(new Child2(), new Child2().say());
var s3 = new Child2();
var s4 = new Child2();
s3.play.push(4);
console.log(s3.play, s4.play, s3.hasOwnProperty("play"), "test2");

3.组合方式

// 缺点:父级构造函数执行了两遍
function Parent3 () {
    this.name = "parent3";
    this.play = [1, 2, 3];
}
function Child3 () {
    Parent3.call(this); // 关键1
    this.type = "child3";
}
Parent3.prototype.say = function () {
    console.log("hello3");
};
Child3.prototype = new Parent3(); // 关键2
var s5 = new Child3();
var s6 = new Child3();
s5.play.push(4);
console.log(s5, s6, s5.hasOwnProperty("play"), "test");

4.组合方式优化1

// 缺点:实例属性constructor指向父级构造函数,使用instanceof不能正确判断对象类型
function Parent4 () {
    this.name = "parent4";
    this.play = [1, 2, 3];
}
function Child4 () {
    Parent4.call(this);
    this.type = "child4";
}
Parent4.prototype.say = function () {
    console.log("hello4");
};
Child4.prototype = Parent4.prototype;
Child4.prototype.constructor = Child4; // 新增代码,让实例指向其真实的构造函数
var s7 = new Child4();
var s8 = new Child4();
s7.play.push(4);
console.log(s7, s8);
// 判断是子原型Child4实例化还是Parent4直接实例化的
console.log(s7 instanceof Child4, s8 instanceof Parent4); // 判断不了
console.log(s7.constructor, s8.constructor, s7.hasOwnProperty("play"), "test");

5.组合方式优化2

function Parent5 () {
    this.name = "parent5";
    this.play = [1, 2, 3];
}
function Child5 () {
    Parent5.call(this);
    this.type = "child5";
}
Parent5.prototype.say = function () {
    console.log("hello5");
};
Child5.prototype = Object.create(Parent5.prototype);
Child5.prototype.constructor = Child5;
var s9 = new Child5();
var s10 = new Child5();
s9.play.push(4);
console.log(s9 instanceof Child5, s9 instanceof Parent5);
console.log(s9.constructor, s10.constructor, s9.hasOwnProperty("play"), "test11");
参考

构造函数的继承

非构造函数的继承

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

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

相关文章

  • JS面向对象之一 【概述】

    摘要:更形象的我们还可以将面向对象理解为一种宗教信仰。这就导致面向对象教的程序员们在写时就很难受。所以为了满足信仰面向对象教的需求通过构造函数的形式模拟了伪类。这个套路的核心就是类那么里没有类所以其实是通过构造函数来模拟的伪类。 JS面向对象之一 【概述】 在学习JS的面向对象之前,我们应该先自问这样几个问题: 面向对象是什么意思? 学习面向对象的核心是什么? 为什么要学习面向对象?(它的...

    JohnLui 评论0 收藏0
  • 面向对象的 JavaScript

    摘要:是完全的面向对象语言,它们通过类的形式组织函数和变量,使之不能脱离对象存在。而在基于原型的面向对象方式中,对象则是依靠构造器利用原型构造出来的。 JavaScript 函数式脚本语言特性以及其看似随意的编写风格,导致长期以来人们对这一门语言的误解,即认为 JavaScript 不是一门面向对象的语言,或者只是部分具备一些面向对象的特征。本文将回归面向对象本意,从对语言感悟的角度阐述为什...

    novo 评论0 收藏0
  • 体验javascript之美6:如果你觉得什么都会了或者不知道js学什么了看这里-面向对象编程

    摘要:面向过程函数式编程面向对象编程第二个并不是大家理解的那样,我们先说举个现实例子就明白了。多说一句函数是编程是非常强大也是我最喜欢的,以后再说,我们先说面向对象编程。 概述 当大家已经把js的语言基础理解了,然后能够写出一些简单的例子了,这个时候基本上达到了一年工作经验的水平,而自己能够独立的写一些小功能,完成一些小效果,或者临摹修改一些比较复杂的插件的时候差不多就是两年工作经验的水平,...

    changfeng1050 评论0 收藏0
  • JS对象(1)重新认识面向对象

    摘要:对象重新认识面向对象面向对象从设计模式上看,对象是计算机抽象现实世界的一种方式。除了字面式声明方式之外,允许通过构造器创建对象。每个构造器实际上是一个函数对象该函数对象含有一个属性用于实现基于原型的继承和共享属性。 title: JS对象(1)重新认识面向对象 date: 2016-10-05 tags: JavaScript 0x00 面向对象 从设计模式上看,对象是...

    superw 评论0 收藏0
  • JS面向对象一:MVC的面向对象封装

    摘要:自己的理解的第一个参数就是的值如果没用默认是那个调用函数的当前的对象在全局作用域中就是被隐藏的所以不写且在全局作用于调用函数的时候就是可以使用或者自己指定的指向 JS面向对象一:MVC的面向对象封装 MDNjavascript面向对象 面向对象(Object-Oriented) showImg(https://segmentfault.com/img/remote/1460000016...

    Scliang 评论0 收藏0

发表评论

0条评论

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