详谈js原型继承的一些问题

当我们使用原型链继承时,需要谨慎的定义原型上的方法和属性,因为这可能带来意外的结果。

一、谨慎的定义原型上的方法。

当我们想为一个构造函数的原型上定义一个方法时,一定要在更改原型后再定义,否则新的原型对象上不会有定义的这个方法,导致与我们预期的结果不同。例:

function superObj(){}
superObj.prototype.sayHi=function sayHi(){
  console.log('hi');
};
superObj.prototype={
  name:'Poly'
};
var obj=new superObj();
obj.sayHi();//报错!! superObj.sayHi is not a function

正确操作如下

function superObj(){}
superObj.prototype={
  name:'Poly'
};
superObj.prototype.sayHi=function sayHi(){
  console.log('hi');
};
var obj=new superObj();
obj.sayHi();// 'hi'

二、不要使用对象字面量给原型创建属性/方法。

使用对象字面量,就会新创建一个对象,并把新对象的引用地址赋值给构造函数的prototype。例

function superObj(){}
superObj.prototype={
  sayHi:function sayHi(){
    console.log('hi');
  }
}

正确操作如下:

function superObj(){}
superObj.prototype.sayHi=function sayHi(){
  console.log('hi');
}

三、对象实例与原型存在直接对应关系。

意思就是说当一个对__proto__就会保存原型的引用地址,即使构造函数的prototype发生改变,也不会对之前创建的实例中的__proto__产生影响。例

function superObj(){}
superObj.prototype.say=function() {
  console.log('hello');
}
var obj=new superObj();
superObj.prototype={
  say:function() {
    console.log('world');
  }
};
var obj2=new superObj();
obj.say();//'hello'
obj2.say();//'world'

四、最好不要给原型上定义值为引用类型的属性。

如果在原型上定义值为引用类型的属性,那么所有实例都会共享该属性值(引用类型值,指向同一个对象),当其中一个实例修改该引用类型上的值或属性时,所有实例上的都会发生改变。因此值为引用类型的属性,最好在构造函数中定义。例

function superObj(){}
superObj.prototype.ary=[1,2,3];
var obj1=new superObj();
var obj2=new superObj();
obj1.ary[0]=0;//obj1.ary和obj2.ary指向的是同一个数组,当obj1修改此数组时,obj2.ary也会发生改变
console.log(obj2.ary[0]);//0

如果不想让实例共享同一个引用对象,那么就应该在构造函数中进行定义。例

function superObj(){
  this.ary=[1,2,3];
}
var obj1=new superObj();
var obj2=new superObj();
obj1.ary[0]=0;//obj1.ary和obj2.ary指向的不是同一个数组,所以修改obj1.ary不会影响obj2.ary
console.log(obj2.ary[0]);//1

以上这篇详谈js原型继承的一些问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 浅谈javascript的原型继承

    请看源码: 复制代码 代码如下: function clone(o) { var F = function(){}; F.prototype = o; return new F(); } 首先看ext(4.1的1896行开始)的原型式继承. 复制代码 代码如下: var TemplateClass = function(){}; var ExtObject = Ext.Object = { chain: function (object) { TemplateClass.prototype =

  • 浅析JS原型继承与类的继承

    我们先看JS类的继承 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>JS类的继承</title> </head> <body> /* -- 类式继承 -- */ <script type="text/javascript"> //先声明一个超类 var Animal = function

  • javascript原型继承工作原理和实例详解

    先为大家分享JS原型继承实例,供大家参考,具体内容如下 一.JS原型继承 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>JS原型继承</title> </head> <body> <!--原型继承--> <script type="text/javascript"> //cl

  • 浅析JavaScript原型继承的陷阱

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

  • JavaScript中的原型继承基础学习教程

    大多数编程语言中,都有类和对象,一个类可以继承其他类. 在JavaScript中,继承是基于原型的(prototype-based),这意味着JavaScript中没有类,取而代之的是一个对象继承另一个对象.:) 1. 继承, the proto 在JavaScript中,当一个对象rabbit继承另一了对象animal时,这意味着rabbit对象中将会有一个特殊的属性:rabbit.__proto__ = animal; 当访问rabbit对象时,如果解释器在rabbit中不能找到属性,那么它

  • 再谈javascript原型继承

    真正意义上来说Javascript并不是一门面向对象的语言,没有提供传统的继承方式,但是它提供了一种原型继承的方式,利用自身提供的原型属性来实现继承. 原型与原型链 说原型继承之前还是要先说说原型和原型链,毕竟这是实现原型继承的基础. 在Javascript中,每个函数都有一个原型属性prototype指向自身的原型,而由这个函数创建的对象也有一个__proto__属性指向这个原型,而函数的原型是一个对象,所以这个对象也会有一个__proto__指向自己的原型,这样逐层深入直到Object对象的

  • JavaScript原型继承_动力节点Java学院整理

    在传统的基于Class的语言如Java.C++中,继承的本质是扩展一个已有的Class,并生成新的Subclass. 由于这类语言严格区分类和实例,继承实际上是类型的扩展.但是,JavaScript由于采用原型继承,我们无法直接扩展一个Class,因为根本不存在Class这种类型. 但是办法还是有的.我们先回顾Student构造函数: function Student(props) { this.name = props.name || 'Unnamed'; } Student.prototyp

  • 关于JavaScript中原型继承中的一点思考

    我们先看一段传统的继承代码: 复制代码 代码如下: //定义超类 function Father(){ this.name = "父亲"; } Father.prototype.theSuperValue = ["NO1","NO2"]; //定义子类 function Child(){ } //实现继承 Child.prototype = new Father(); //修改共享数组 Child.prototype.theSuperValue.

  • JavaScript 原型继承

    Object.prototype JavaScript是基于原型继承的,任何对象都有一个prototype属性.Object.prototype是所有对象的根,并且不可改变. 复制代码 代码如下: Object.prototype=null; alert(Object.prototype);//[object Object] Object与Object.prototype Object继承于Object.prototype,增加一个属性给Object.prototype上,同时也会反应到Obje

  • js原型继承的两种方法对比介绍

    在实际的项目中,我们通常都是用构造函数来创建一个对象,再将一些常用的方法添加到其原型对象上.最后要么直接实例化该对象,要么将它作为父类,再申明一个对象,继承该父类. 而在继承的时候有两种常用方式,今天我们就来稍作探讨 复制代码 代码如下: //父类 function Person(name){    this.name = name;}; // 子类 function Student(sex){  Person.apply(this,arguments); //继承父类的构造函数  this.s

  • JavaScript的原型继承详解

    JavaScript是一门面向对象的语言.在JavaScript中有一句很经典的话,万物皆对象.既然是面向对象的,那就有面向对象的三大特征:封装.继承.多态.这里讲的是JavaScript的继承,其他两个容后再讲. JavaScript的继承和C++的继承不大一样,C++的继承是基于类的,而JavaScript的继承是基于原型的. 现在问题来了. 原型是什么?原型我们可以参照C++里的类,同样的保存了对象的属性和方法.例如我们写一个简单的对象 复制代码 代码如下: function Animal

随机推荐