理解JavaScript中的原型

学习JavaScript有一段时间了,感觉原型那块儿又有点混乱了,现在写个笔记整理一下思路。

什么是原型

每创建一个函数,这个函数都会自带一个属性prototype指向一个原型对象,最初这个原型对象只包含一个属性constructor,这是指向我们创建的那个函数的指针。也就是说函数和原型对象分别通过prototype和constructor这两个属性(指针)能找到对方。

我们可以通过fn.prototype.propertyName=value来给原型对象继续添加属性和方法。这些属性和方法区别于在函数中书写的实例属性和方法。为什么会有这种区别或者说这种区别是怎么做到的呢?来看看创建一个实例后发生了什么。以下面的代码来说明:

function Person(name,age){
    this.name=name,
    this.age=age;
}
Person.prototype.hobby = ["running","swimming","tennis"];
Person.prototype.country="China";
Person.prototype.showName=function(){alert(this.name);};

var person1 = new Person("anna",10);

这里创建了一个实例person1,我们知道通过new方法创建的实例,原来Person中的this会被新创建的实例即person1取代,也就是说通过这样的方式,我们为对象person1增加了属性name和age,这些是person1自己所拥有的属性,独立于其他Person的实例,叫做实例属性。

同时,每创建一个实例,这个实例会自带一个内部属性[prototype],它是一个指向构造函数的原型对象的引用。也就是说person1对象其实现在包括了这么三个属性:

person1={
   prototype:Person.prototype,
   name:"anna",
   age:10
}

这个内部属性一般来说是不可以通过脚本来访问到的,那它有什么用呢?在进行属性标识符查找的时候会用到它。

引擎在读到某个对象的属性时,会首先查找实例属性中有没有这个属性,如果有则停止,没有则通过内部属性[prototype]找到其关联的原型对象,看原型对象中有没有相应的属性。

实例属性和原型属性同名

这里需要注意,如果我们又为实例添加了一个和原型对象中同名的属性,或者说我们“重写”原型中的属性会发生什么。这得分属性是原始值类型还是引用类型。

  • 原始类型

    同名的实例属性会屏蔽掉原型对象中的同名属性,这里的屏蔽的意思是,这个属性变成了实例自己的实例属性了,跟原型对象中的属性半毛钱关系没有,它根本就不会“重写”原型对象中的属性,根本就是两个值,在内存中有两个空间。通过hasOwnProperty()可以看到已经成为自己的实例属性了:

person1.country="USA";  //重写属性
alert(person1.hasOwnProperty("country"));//true

可通过delete person1.country来删除实例属性,这样就又可以访问到原型对象中的属性了。

  • 引用类型

    而引用类型就不一样了,所有实例都共享原型对象中这个引用类型的属性,通过任何实例对引用类型数据进行的更改都是对同一个即原型对象中的这个属性进行更改,它不会像原始值类型属性一样通过”重写”的方式变成自己的实例属性:

person1.hobby.push("hiking");
alert(person1.hasOwnProperty("hobby"));//false

可看出通过hasOwnProperty来检测,发现重写后没有变成自己的实例属性。

问题:原型对象showName方法中的this是实例对象?解释为谁调用this就是谁?

由于时间关系先写到这儿,后面还会有补充。。。。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-08 03:56:19

理解JavaScript中的原型的相关文章

理解javascript中的原型模式

一.为什么要用原型模式. 早期采用工厂模式或构造函数模式的缺点:  1.工厂模式:函数creatPerson根据接受的参数来构建一个包含所有必要信息的person对象,这个函数可以被无数次的调用,工厂模式尽管解决了创建多个相似对象的问题,却没有解决对象识别的问题(返回的是自定义的一个对象o,不明确对象o的类型).  2. 构造函数模式:构造函数的调用和其他oo语言一样,用new操作符来构建一个Person的实例:javascript中的构造函数也是函数(所以也可以直接像普通函数那样直接调用方法名

简单理解javascript中的原型对象,实现对之间共享属性和行为

javascript中提供了构造函数,能够方便的创建对象.典型的构造函数如下: function Person(name, age) { this.name = name; this.age = age; this.say = function () { return this.name + ',' + this.age;; } 之后就可以用new和构造函数创建多个对象.javascript中,类的不同对象之间,属性和方法都是独立的.什么意思呢?java中类的不同对象之间,成员变量是独立的(每个

理解javascript中的原型和原型链

原型 大家都知道,JavaScript 不包含传统的类继承模型,而是使用 prototype 原型模型.代码实现大概是这样子的 ? 1 2 3 4 5 6 7 8 9 10 11 12 function Student(name){  this.name = name; }   var Kimy = new Student("Kimy");   Student.prototype.say = function(){  console.log(this.name + "say&

如何理解JavaScript中的原型和原型链

首先是一张关系图,避免抽象化理解时产生的困难 Function对象 函数对象是JavaScript学习中不可避免的一部分,而且这一部分相对重要且抽象 函数的创建方式有2种: 字面量创建 var foo = function(){ console.log("test"); } new 关键字创建实例对象 //let 函数名 = new Function(“参数列表”,”函数体”); let sum = new Function("num1,num2","re

一句话简单理解javascript中的原型对象

通过构造函数F创建的对象实例p 这个对象p的原型对象是 构造函数中prototype属性指向的对象s,这个对象p中也有个非标准的__proto__属性指向构造函数prototype所指向的对象s,所以就有 p.__proto__ === F.prototype;在对象P的原型对象s中有个属性constructor属性,指向的是构造函数本身.如果对象p的原型对象s被重写,那么P的构造函数不再是F,而是Object 例如: 1 function F(){}; 2 var p = new F(); 3

深入理解JavaScript中创建对象模式的演变(原型)

创建对象的模式多种多样,但是各种模式又有怎样的利弊呢?有没有一种最为完美的模式呢?下面我将就以下几个方面来分析创建对象的几种模式: Object构造函数和对象字面量方法 工厂模式 自定义构造函数模式 原型模式 组合使用自定义构造函数模式和原型模式 动态原型模式.寄生构造函数模式.稳妥构造函数模式 第一部分:Object构造函数和对象字面量方法 我之前在博文<javascript中对象字面量的理解>中讲到过这两种方法,如何大家不熟悉,可以点进去看一看回顾一下.它们的优点是用来创建单个的对象非常方

图解JavaScript中的原型链

转自:http://www.jianshu.com/p/a81692ad5b5d typeof obj 和 obj instanceof Type 在JavaScript中,我们经常用typeof obj和obj instanceof Type来识别类型,那么两者的区别在哪?先来看两段代码 <!--typeof obj的方式判断--> <script>    var str = "toby";    console.log(typeof str);// stri

理解JavaScript中函数的使用

函数是进行模块化程序设计的基础,编写复杂的Ajax应用程序,必须对函数有更深入的了解. JavaScript中的函数不同于其他的语言,每个函数都是作为一个对象被维护和运行的.通过函数对象的性质,可以很方便的将一个函数赋值给一个变量或者将函数作为参数传递.在继续讲述之前,先看一下函数的使用语法: function func1(…){…} var func2=function(…){…}; var func3=function func4(…){…}; var func5=new Function(

理解 JavaScript 中的 this

前言 理解this是我们要深入理解 JavaScript 中必不可少的一个步骤,同时只有理解了 this,你才能更加清晰地写出与自己预期一致的 JavaScript 代码. 本文是这系列的第三篇,往期文章: 理解 JavaScript 中的作用域 理解 JavaScript 中的闭包 什么是 this 消除误解 在解释什么是this之前,需要先纠正大部分人对this的误解,常见的误解有: 指向函数自身. 指向它所在的作用域. 关于为何会误解的原因这里不多讲,这里只给出结论,有兴趣可以自行查询资料