原型陷阱

 处理原型问题时,我们需要特别注意一下两种行为。1、当我们对原型对象执行完全替换时,可能会触发原型链中的某种异常2、prototype。constructor属性是不可靠的下面,我们来新建一个简单的构造器函数,并用它再创建两个对象;function Dog() {     this.tail = true; } var benji = new Dog(); var rusty = new Dog();

 /* * 即便在benji和rusty对象创建之后,我们也依然能为Dog();的原型添加属性,并且在属性被添加之前就已经存在的对象 * 也可以随时访问这些新属性。现在,让我们放一个say()方法进去*/ Dog.prototype.say = function () {     return ‘Woof‘; }; /*这样,上面的两个对象都可以访问该新方法了;*/ console.log(benji.say());//Woof console.log(rusty.say());//Woof /*检查一下这些对象的构造器函数,就会发现一切正常*/ console.log(benji.constructor === Dog); //true console.log(rusty.constructor === Dog); //true

 /*现在我们用一个新对象完全覆盖掉原有的原型对象;*/ Dog.prototype = {     paws : 4,     hair : true };

 /*事实证明,这会使原有对象不能访问原型的新增属性,他们依然通过那个神秘的链接与原有的原型对象保持联系*/ console.log(typeof benji.paws); //undefined console.log(benji.say()); //Woof console.log(typeof benji.__proto__.say); //function console.log(typeof benji.__proto__.paws); //undefined

 /*而我们之后创建的所有对象使用的都是被更新后的prototype对象.*/

 var lucy = new Dog();// console.log(lucy.say());//Uncaught TypeError: lucy.say is not a function console.log(lucy.paws); //4

 /*并且,其秘密链接_proto_也指向了新的prototype对象;*/ console.log(typeof lucy.__proto__.say); //undefined console.log(typeof lucy.__proto__.paws); //number

 /*但这时候,新对象的constructor属性就不能保持正确了,原本原本应该是Dog();的引用只想了Object.*/ console.log(lucy.constructor); //function Object() { [native code] } console.log(benji.constructor);/*  Dog() {      this.tail = true;  } */

 /*当然,我们可以通过重新设置constructor属性来解决上述所有的异常行为*/ function Dog(){} Dog.prototype = {}; console.log(new Dog().constructor ===Dog);//false

 Dog.prototype.constructor = Dog; console.log(new Dog().constructor === Dog);//true

 /* * 声明: * 本文借鉴JavaScript面向对象编程指南(第二版) * */
时间: 2024-08-11 03:31:03

原型陷阱的相关文章

javascript --- 原型初探七日谈(三)

原型陷阱: 在处理原型问题上时,我们要注意两种行为. 1. 当我们对原型对象执行完全替换的时候,有可能会触发原型链的某种异常. 2. prototype.constructor 属性是不可靠的. 下面,我们新建一个构造函数,并创建两个对象: var her = fucntion(){ this.name = 'Anna'; } var she1 = her(); var she2 = her(); 即使在对象she1和she2对象被创建之后,我们仍然可以对her()的原型添加属性,并且之前创建的

Javascript面向对象编程(二)--- 构造函数的继承

这个系列的第一部分,主要介绍了如何"封装"数据和方法,以及如何从原型对象生成实例 今天要介绍的是,对象之间的"继承"的五种方法. 比如,现在有一个"动物"对象的构造函数. function Animal(){ this.species = "动物"; } 还有一个"猫"对象的构造函数. function Cat(name,color){ this.name = name; this.color = colo

JavaScript原型继承的陷阱

JavaScript原型继承的陷阱 JavaScript默认采用原型继承.虽然没有类(class)的概念,它的函数(function)可以充当构造器(constructor).构造器结合this,new可以构建出类似Java的类.因此,JavaScript通过扩展自身能模拟类式(class-based)继承. JavaScript和其它面向对象语言一样,对象类型采用引用方式.持有对象的变量只是一个地址,而基本类型数据是值.当原型上存储对象时,就可能有一些陷阱. 先看第一个例子 var creat

Prototype原型模式

通过构造函数的弊端引出原型概念 先看一个一只猫的构造函数 function Cat(name,color){ this.name = name; this.color = color; this.type = "猫科动物"; this.eat = function(){alert("吃老鼠");}; } var cat1 = new Cat("大毛","黄色"); var cat2 = new Cat ("二毛&qu

JavaScript 面向对象 (prototype 原型模式)

一. JavaScript 设计思想 1994年,网景公司(Netscape)发布了Navigator浏览器0.9版.这是历史上第一个比较成熟的网络浏览器,轰动一时.但是,这个版本的浏览器只能用来浏览,不具备与访问者互动的能力.比如,如果网页上有一栏"用户名"要求填写,浏览器就无法判断访问者是否真的填写了,只有让服务器端判断.如果没有填写,服务器端就返回错误,要求用户重新填写,这太浪费时间和服务器资源了. 因此,网景公司急需一种网页脚本语言,使得浏览器可以与网页互动.工程师_Brend

JavaScript的陷阱

这本来是翻译Estelle Weyl的<15 JavaScript Gotchas>,里面介绍的都是在JavaScript编程实践中平时容易出错或需要注意的地方,并提供避开这些陷阱的方法,总体上讲,就是在认清事物本质的基础样要坚持好的编程习惯,其实这就是Douglas Crockford很久以前提出的JavaScript风格要素问题了,有些内容直接是相同的,具体请看<Javascript风格要素(1)>和<Javascript风格要素(2)>.在翻译的过程中,我又看到了

JavaScript中的this陷阱的最全收集--没有之一

原文:JavaScript中的this陷阱的最全收集--没有之一 当有人问起你JavaScript有什么特点的时候,你可能立马就想到了单线程.事件驱动.面向对象等一堆词语,但是如果真的让你解释一下这些概念,可能真解释不清楚.有句话这么说:如果你不能向一个6岁小孩解释清楚一个东西,那么你自己也不懂这个东西.这句话或许有点夸张,但是极其有道理.个人觉得,如果需要掌握一门语言,掌握它的API只是学了皮毛,理解这门语言的精髓才是重点.提及JavaScript的精髓,this.闭包.作用域链.函数是当之无

【JavaScript】JavaScript中的陷阱大集合

本文主要介绍怪异的Javascript,毋庸置疑,它绝对有怪异的一面.当软件开发者开始使用世界上使用最广泛的语言编写代码时,他们会在这个过 程中发现很多有趣的“特性”.即便是老练的Javascript开发者也可以在本文找到一些有趣的新陷阱,请留意这些陷阱,当然也可以尽情享受由这些陷阱 带来的“乐趣”! AD: 本文主要介绍怪异的Javascript,毋庸置疑,它绝对有怪异的一面.当软件开发者开始使用世界上使用最广泛的语言编写代码时,他们会在这个过 程中发现很多有趣的“特性”.即便是老练的Java

编写高质量代码改善C#程序的157个建议[C#闭包的陷阱、委托、事件、事件模型]

前言 本文已更新至http://www.cnblogs.com/aehyok/p/3624579.html .本文主要学习记录以下内容: 建议38.小心闭包中的陷阱 建议39.了解委托的实质 建议40.使用event关键字对委托施加保护 建议41.实现标准的事件模型 建议38.小心闭包中的陷阱 首先我们先来看一段代码: class Program { static void Main(string[] args) { List<Action> list = new List<Action