资讯专栏INFORMATION COLUMN

JavaScript对象的深入理解(二)

tommego / 391人阅读

摘要:原型的概念不同于构造函数模式创建对象只能单级即成,得益于原型链的概念,原型模式可实现类似其他语言的多级继承。组合使用构造函数与原型模式单一使用原型对象的问题在于所有属性皆共享,若不想共享某属性,则可放入构造函数中。

之前提到,构造函数方法创建对象存在着方法不共享的问题,因此引申出了原型模式创建对象

原型模式

原型模式旨在创建一个模版对象,该对象的所有属性和方法被其实例所共享。

原型的概念

不同于构造函数模式创建对象只能单级即成,得益于原型链的概念,原型模式可实现类似其他OOP语言的多级继承。

原型链:一系列有继承关系的函数(对象)中[[prototype]]属性自底向上的指向

先给一个例子:

function Person() {
    
}

Person.prototype = {
      constructor: Person,
    name: "Jonathan",
    age: 23,
      job: developer,
      sayName: function() {
        console.log(this.name);
    }
}

person1 = new Person();
person2 = new Person();

该例子中各对象的关系如下

//

每一个函数(对象)都可以视为一个模版,向上看,该对象的[[prototype]]

创建原型对象
function Person() {
}

Person.prototype = {
      constructor: Person,
    name: "Jonathan",
    age: 23,
      job: developer,
      sayName: function() {
        console.log(this.name);
    }
}

var person1 = new Person();
person1.sayName(); //"Jonathan"

var person2 = new Person();
person2.sayName(); //"Jonathan"

console.log(person1.sayName == person2.sayName); //true

要点

先命名一个空函数

用对象字面量方式,为该函数的.prototype属性添加原型属性及方法

为了constructor属性的正确指向,应先把constructor指向该对象

原型对象的问题

由于众多实例共享原型的属性,因此改变其中某个实例的属性会影响到全局,造成属性污染,例子如下:

function Person(){
}

Person.prototype = {
    constructor: Person,
    name : "Nicholas",
    age : 29,
    job : "Software Engineer",
    friends : ["Shelby", "Court"],
    sayName : function () {
        alert(this.name);
    }
};

var person1 = new Person();
var person2 = new Person();

person1.friends.push("Van");

alert(person1.friends);    //"Shelby,Court,Van"
alert(person2.friends);    //"Shelby,Court,Van"
alert(person1.friends === person2.friends);  //true

可见,person1的friends属性污染了person2的friends属性。为避免这种情况,引入组合构造函数与原型模式。

组合使用构造函数与原型模式

单一使用原型对象的问题在于所有属性皆共享,若不想共享某属性,则可放入构造函数中。

function Person(name, age, job){
   this.name = name;
    this.age = age;
    this.job = job;
    this.friends = ["Boy next door", "Deep dark fantasy"];
}

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,Court,Van"
alert(person2.friends);    //"Shelby,Court"
alert(person1.friends === person2.friends);  //false
alert(person1.sayName === person2.sayName);  //true

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

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

相关文章

  • 深入理解JavaScript

    摘要:深入之继承的多种方式和优缺点深入系列第十五篇,讲解各种继承方式和优缺点。对于解释型语言例如来说,通过词法分析语法分析语法树,就可以开始解释执行了。 JavaScript深入之继承的多种方式和优缺点 JavaScript深入系列第十五篇,讲解JavaScript各种继承方式和优缺点。 写在前面 本文讲解JavaScript各种继承方式和优缺点。 但是注意: 这篇文章更像是笔记,哎,再让我...

    myeveryheart 评论0 收藏0
  • 由ES规范学JavaScript():深入理解“连等赋值”问题

    摘要:有这样一个热门问题其实这个问题很好理解,关键要弄清下面两个知识点引擎对赋值表达式的处理过程赋值运算的右结合性一赋值表达式形如的表达式称为赋值表达式。赋值表达式是右结合的。 有这样一个热门问题: var a = {n: 1}; var b = a; a.x = a = {n: 2}; alert(a.x); // --> undefined alert(b.x); // --> {n: ...

    JasonZhang 评论0 收藏0
  • JavaScript 异步

    摘要:从最开始的到封装后的都在试图解决异步编程过程中的问题。为了让编程更美好,我们就需要引入来降低异步编程的复杂性。写一个符合规范并可配合使用的写一个符合规范并可配合使用的理解的工作原理采用回调函数来处理异步编程。 JavaScript怎么使用循环代替(异步)递归 问题描述 在开发过程中,遇到一个需求:在系统初始化时通过http获取一个第三方服务器端的列表,第三方服务器提供了一个接口,可通过...

    tuniutech 评论0 收藏0
  • 深入理解JavaScript执行上下文和执行栈

    摘要:执行上下文和执行栈是中关键概念之一,是难点之一。理解执行上下文和执行栈同样有助于理解其他的概念如提升机制作用域和闭包等。函数执行完成,函数的执行上下文出栈,并且被销毁。 前言 如果你是一名 JavaScript 开发者,或者想要成为一名 JavaScript 开发者,那么你必须知道 JavaScript 程序内部的执行机制。执行上下文和执行栈是JavaScript中关键概念之一,是Ja...

    silenceboy 评论0 收藏0
  • 深入理解JavaScript执行上下文和执行栈

    摘要:执行上下文和执行栈是中关键概念之一,是难点之一。理解执行上下文和执行栈同样有助于理解其他的概念如提升机制作用域和闭包等。函数执行完成,函数的执行上下文出栈,并且被销毁。 前言 如果你是一名 JavaScript 开发者,或者想要成为一名 JavaScript 开发者,那么你必须知道 JavaScript 程序内部的执行机制。执行上下文和执行栈是JavaScript中关键概念之一,是Ja...

    leiyi 评论0 收藏0

发表评论

0条评论

tommego

|高级讲师

TA的文章

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