秒懂javascript的原型(prototype)对象、原型链的前世今生

上文中我们通过原型方式,解决了多个实例的方法共享问题,接下来,我们就来搞清楚原型(prototype),原型链的来龙去脉.

function CreateObj(uName) {
            this.userName = uName;
        }
        CreateObj.prototype.showUserName = function(){
            return this.userName;
        }
        var obj1 = new CreateObj(‘ghostwu‘);
        var obj2 = new CreateObj(‘卫庄‘);

1,每个函数都有一个原型属性(prototype) , 这个属性是一个指针,指向构造函数的原型对象( CreateObj.prototype), 如上图中的第1根绿色的线

2,在默认情况下,所有原型对象都会自动获得一个constructor属性,该属性的作用上文已经解释过,该属性包含一个指向prototype属性所在的函数,如上图的第2根绿色的线

3,所有的实例( 通过构造函数new出来的, 原型对象[ 如CreateObj.prototype]等 )都包含一个隐式原型(__proto__),该指针指向实例的构造函数的原型对象,

如上图中的第3根线和第4根线. obj1的构造函数是CreateObj, CreateObj的原型对象是CreateObj.prototype, obj2同理,所以:

obj1.__proto__ === CreateObj.prototype //true

obj2.__proto__ === CreateObj.prototype //true

4,写在构造函数中, 为this赋值的属性和方法, 在画图的过程中,把他们画在对象上面,如userName这个是给对象赋值的属性,所以在obj1和obj2这两个对象上都会存在一个属性userName

5,写在原型对象上的方法或者属性,应该把他们画在原型对象上,如

CreateObj.prototype.showUserName = function(){

return this.userName;

}

showUserName这个方法就要画在图中CreateObj.prototype上面

6,当一个对象访问属性和方法的时候,他的访问规则叫(就近原则), 规则如下:

当实例上面,存在属性或者方法时,直接用实例上面的,

如果实例上面不存在属性和方法,就会沿着实例的__proto__指针指向的原型对象继续往上查找,如果找不到,值就是undefined.

console.log( obj1.showUserName() ); //ghostwu

console.log( obj2.showUserName() ); //卫庄

在obj1,obj2上面是不存在showUserName这个方法的,所以会顺着__proto__查找到CreateObj.prototype原型对象上的showUserName方法

如果,把CreateObj.prototype原型对象上的showUserName注释掉,那么obj1.showUserName和obj2.showUserName就会报错

// CreateObj.prototype.showUserName = function(){

// return this.userName;

// }

function CreateObj(uName) {
            this.userName = uName;
            this.showUserName = function(){
                return ‘100‘;
            }
        }
        CreateObj.prototype.showUserName = function(){
            return this.userName;
        }

        var obj1 = new CreateObj(‘ghostwu‘);
        var obj2 = new CreateObj(‘卫庄‘);

        console.log( obj1.showUserName() ); //100
        console.log( obj2.showUserName() ); //100

如果在构造函数中为this添加一个showUserName方法, 那么obj1和obj2就会直接调用this上面的,因为这两个方法会被画在图中的实例上,所以:

console.log( obj1.showUserName === obj2.showUserName ); //false

现在,你应该能明白,把属性和方法写在构造函数的原型对象(prototype)上之后,能实现多个实例属性和方法的共享的原理了吧

什么是原型链?

在前面,我有说过,所有的实例(包括原型对象)都有一个隐式原型__proto__,那么CreateObj.prototype这个原型对象,他的__proto__指向谁呢?

function CreateObj(uName) {
            this.userName = uName;
            this.showUserName = function () {
                return ‘100‘;
            }
        }
        CreateObj.prototype.showUserName = function () {
            return this.userName;
        }

        console.log( CreateObj.prototype.__proto__ ); //指向Object.prototype
        console.log( CreateObj.prototype.__proto__ === Object.prototype ); //true

CreateObj.prototype.__proto__指向的是Object.prototype, 通过 全等运算符 (===) 测试之后为true

Object.prototype.__proto__ 指向的是NULL;

所以obj1.__proto__.__proto__.__proto__ === NULL。

这就是原型链,通过隐式原型把一些构造函数层层的串起来,通过上面这个图,就知道,为什么自定义的对象能调用toString, valueOf,等方法了吧?

因为所有的对象都是继承自Object.

出处:http://www.cnblogs.com/ghostwu 作者:ghostwu。

原文地址:https://www.cnblogs.com/art-poet/p/12112465.html

时间: 2024-10-06 01:40:11

秒懂javascript的原型(prototype)对象、原型链的前世今生的相关文章

[js高手之路]一步步图解javascript的原型(prototype)对象,原型链

我们接着上文继续,我们通过原型方式,解决了多个实例的方法共享问题,接下来,我们就来搞清楚原型(prototype),原型链的来龙去脉. function CreateObj(uName) {             this.userName = uName;         }         CreateObj.prototype.showUserName = function(){             return this.userName;         }         va

原型prototype、原型链__proto__、构造器constructor

创建函数时,会有原型prototype,有原型链__proto__,有constructor.(构造函数除外,没有原型) . prototype原型:是对象的一个属性(也是对象),使你有能力向对象添加属性和方法. __proto__原型链:指向创建它的函数对象的原型对象prototype. constructor构造器:返回创建此对象的函数. 创建一个函数 这个函数的constructor返回的是js底层的函数Function,它的原型链__proto__是function.__proto__是

关于构造函数和原型prototype对象的理解

构造函数     1.什么是构造函数 构造函数,主要用于对象创建的初始化,和new运算符一起用于创建对象,一个类可以有多个构造函数,因为函数名相同,所以只能通过参数的个数和类型不同进行区分,即构造函数的重构, 如果没有定义构造函数,那么该类会自动生成一个空参数的构造函数. 在javascript中,对象创建有二种方式:对象字面量和使用new表达式. 对象字面量,每创建一个对象都要重新定义一次语句,不便于创建大量相同类型的对象 new表达式,配合构造函数使用,例如var person1 = new

JavaScript——中的prototype(原型)

JS中的prototype是JS中比较难理解的一个部分 本文基于下面几个知识点: 1 原型法设计模式 在.Net中可以使用clone()来实现原型法 原型法的主要思想是,现在有1个类A,我想要创建一个类B,这个类是以A为原型的,并且能进行扩展.我们称B的原型为A. 2 javascript的方法可以分为三类: a 类方法 b 对象方法 c 原型方法 例子: function People(name){  this.name=name;  //对象方法  this.Introduce=functi

[js高手之路]原型对象(prototype)与原型链相关属性与方法详解

一,instanceof: instanceof检测左侧的__proto__原型链上,是否存在右侧的prototype原型. 我在之前的两篇文章 [js高手之路]构造函数的基本特性与优缺点 [js高手之路]一步步图解javascript的原型(prototype)对象,原型链 已经分享过了. function CreateObj(uName) {             this.userName = uName;             this.showUserName = function

03. JavaScript高级(3/5)(原型链讲解)

一.原型以及原型链 基础概念: 实例对象的__proto__和构造函数的原型prototype指向相同 实例对象中的__proto__原型指向的是构造函数中的prototype原型 实例对象中的__proto__是原型,是浏览器使用的 构造函数中的prototype是原型,是程序员使用的 实例对象中的proto指向的是构造函数中的prototype所指向的原型对象, 原型链:是一种关系,实例对象和原型对象之间的关系,这种关系是通过实例对象中的原型(proto)来联系的. 改变原型链指向 构造函数

javascript 创建对象及对象原型链属性介绍

我们知道javascript里定义一个普通对象的方法,如: let obj = {}; obj.num = 1; obj.string = 'string'; obj.func = function(){alert('func')}; obj.arr = ['x','y']; console.log(obj.num); //1 console.log(obj.string); // "string" console.log(obj.func); //function(){alert('

javascript的oop——>>> [__proto__ 与 prototype/原型链/原型属性与原型方法/for-in循环]

  前  言  OOP  javascript的oop中的__proto__  与  prototype/原型链/原型属性与原型方法/for-in循环 1  __proto__  与  prototype/原型链   1.prototype(函数的原型):函数才有prototype.prototype是一个对象,指向了当前构造函数的引用地址呢.                       2.__proto__(对象的原型对象):所有对象都要__proto__属性.当用构造函数实例化(new)一

JavaScript学习--Item15 prototype原型和原型链详解

用过JavaScript的同学们肯定都对prototype如雷贯耳,但是这究竟是个什么东西却让初学者莫衷一是,只知道函数都会有一个prototype属性,可以为其添加函数供实例访问,其它的就不清楚了,最近看了一些 JavaScript高级程序设计,终于揭开了其神秘面纱. 每个函数都有一个prototype属性,这个属性是指向一个对象的引用,这个对象称为原型对象,原型对象包含函数实例共享的方法和属性,也就是说将函数用作构造函数调用(使用new操作符调用)的时候,新创建的对象会从原型对象上继承属性和