资讯专栏INFORMATION COLUMN

【翻译】javascript中的prototype

lentrue / 1036人阅读

摘要:构造函数就是一个具有属性的方法,该属性被称作标识具有一个属性,但是没有用户定义它。然而,构造函数的属性可以被改变,并且将影响用这个原型创建的对象。

原文地址:http://dailyjs.com/2012/05/20/js101-prototype/

在花费了很多年研究面向对象编程之后,想在javascript使用是令人失望的。主要是从根源上缺少一个class这样的关键词。然而,javascript的设计不会成为阻碍 -- 精通它基于原型的继承,将会加深你对该语言的理解。

首先我们需要弄清楚面向对象与面向类编程的区别。Javascript提供了我们需要的工具来完成大多数语言的类可以做的事情 -- 我们只需要学习如何正确使用它。

我们简单的看一下prototype属性,看它如何深化我们对javascript的了解。

prototype属性(The prototype Property)

prototype属性是一个内部属性,它被用于实现继承。我们这里的“继承”是一种特定的继承形式。因为状态和方法都由对象承载,所以我们可以说结构、行为和状态都是继承的。这与基于类的语言形成对比,其状态由实例承载,而方法由类承载。

构造函数就是一个具有属性的方法,该属性被称作prototype:

function Animal() {
    
}
console.log(Animal.prototype);

{}标识Animal具有一个prototype属性,但是没有用户定义它。我们可以随意添加值和方法:

function Animal() {  
}

Animal.prototype.type = "Unknown";  
Animal.prototype.weight = 0;  
Animal.prototype.weightUnits = "kg";

Animal.prototype.toString = function() {  
  return this.type + ", " + this.weight + this.weightUnits;
};

var molly = new Animal();  
molly.type = "Dog";  
molly.weight = 28;

console.log(molly.toString());  // Dog, 28kg

这将会输出"Dog, 28kg"。我们可以使用对象字面量将这些赋值分组:

function Animal() {  
}

Animal.prototype = {  
  type: "Unknown",
  weight: 0,
  weightUnits: "kg",

  toString: function() {
    return this.type + ", " + this.weight + this.weightUnits;
  }
};

这样就和你熟悉的类的方式差异不是很大。

动态原型(Dynamic Prototypes)

通过指定值可以给对象动态的添加属性。

var molly = new Animal()  
  , harley = new Animal();

molly.type = "Dog";  
molly.weight = 28;

harley.type = "Dog";  
harley.weight = 38;  
harley.name = "Harley";

console.log(molly);  
console.log(harley);

// { type: "Dog", weight: 28 }
// { type: "Dog", weight: 38, name: "Harley" }

在这里添加name属性只影响了实例。然而,构造函数的属性可以被改变,并且将影响用这个原型创建的对象。

Animal.prototype.weightUnits = "oz";

console.log(molly.toString())  
// Now displays "Dog, 28oz"

这就是为什么人们只会扩展自己的库而不去改变内置原型,或者说只有这么做才是安全的。我们完全有可能改变对象,例如使用String的内置方法做一些不安全的事情:

String.prototype.match = function() {  
  return true;
};

console.log("alex".match(/1234/)); 

输出为true,所以现在我成功的破坏了很多程序都在依赖的基础方法。
改变内置原型也不一定全部是坏的;我们使用它有用的东西,如修补支持更旧版本的ECMAScript在旧版的浏览器。

如果我们替换prototype属性会发生什么?

var molly = new Animal()  
  , harley;

molly.type = "Dog";  
molly.weight = 28;

Animal.prototype = {  
  toString: function() {
    return "...";
  }
};

harley = new Animal;  
harley.type = "Dog";  
harley.weight = 38;

console.log(molly.toString());  
console.log(harley.toString());

// Dog, 28kg
// ...

尽管事实上改变原型会影响所有实例,但是完全替换构造函数的原型不会影响旧实例。为什么?实例具有对原型的引用,而不是离散拷贝。想象它就是这样:使用new关键字创建的每个实例都链接到原始原型。

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

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

相关文章

  • Javascript中的的对象——原型模式(Prototype)

    摘要:使用原型模式添加方法和属性在前面的章节中,已经学习过了如何定义一个构建新对象时使用的构造函数。向构造函数的中添加方法和属性是在对象被创建的时候为对象添加功能的另一种方式。让我们继续使用对象作为构造函数的原型属性。 本文原文来源:《Object-Oriented JavaScript》By Stoyan Stefanov本文翻译来源:赤石俊哉 原创翻译版权申明: 如果您是原文的原作者并且...

    岳光 评论0 收藏0
  • JavaScript中的this陷阱的最全收集--没有之一

    摘要:提及的精髓,闭包作用域链函数是当之无愧的。博客的标题是中的陷阱的最全收集没有之一,很显然这篇博客阐述的是。这是造成很多不熟悉的人深陷陷阱的根源。你应该避免在构造函数里面返回任何东西,因为这可能代 当有人问起你JavaScript有什么特点的时候,你可能立马就想到了单线程、事件驱动、面向对象等一堆词语,但是如果真的让你解释一下这些概念,可能真解释不清楚。有句话这么说:如果你不能向一个6岁...

    KitorinZero 评论0 收藏0
  • 30秒就能理解的 Javascript 代码片段 --- Array篇

    摘要:而这个秒就能理解的代码片段,摒弃了许多不必要的代码,只实现了最核心的部分,不像和那样,考虑参数边界值问题,例如,参数的类型是否符合预期等。使用根据断言函数对数组进行过滤,返回条件为真值的对象。 之前翻译过一篇文章,《我喜欢的5个编程技巧》,里面的一个技巧是借鉴一个网站的代码片段,好奇的小手点下链接后,发现是一个有 47000 多star的仓库,30-seconds-of-code。 仓...

    fox_soyoung 评论0 收藏0
  • 45个实用的JavaScript小贴士、小技巧和最佳实践

    摘要:翻译正文第一次声明变量时,请不要忘记使用关键字声明使用代替空字符串转成布尔值都为每行代码的末尾最好都加上个分号最好给对象都添加上构造函数在使用和尽量小心。 翻译介绍 翻译标题:45 Useful JavaScript Tips, Tricks and Best Practices 翻译来源:http://modernweb.com/2013/12/23/45-useful-java...

    Moxmi 评论0 收藏0
  • 翻译Javascript最佳搭档:强大的join与split

    摘要:不幸的是,这种方法在中失效,因为他们从中错误的去掉了第一个空成员。假设竞走的比赛结果需要保存到数组中。目的就是将竞赛者与他们的记录时间交替的放在数组中。结论我希望我列出的这几条应用足以说明与是最佳搭档。 原文地址:http://javascriptweblog.wordpress.com/2010/11/08/javascripts-dream-team-in-praise-of-sp...

    IntMain 评论0 收藏0

发表评论

0条评论

lentrue

|高级讲师

TA的文章

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