javascript原型原型链 学习随笔

理解原型和原型链。需从构造函数、__proto__属性(IE11以下这个属性是undefined,请使用chrome调试)、prototype属性入手。

JS内置的好多函数,这些函数又被叫做构造函数。如:Object---Array---Function---Math---Date---String---Number---Boolean---Symbol---RegExp。

JS里,所有的对象,都是其构造函数的实例。如{}是Object的一个实例,[]是Array的一个实例。fn() {}是Function的一个实例...

一般情况,我们用对象字面量的方式创建Object的实例。

如:const obj = {}; 这种创建方式是完全等于const obj = new Object();  当然字面量方式是推荐写法。

只要是函数,甭管构造不构造,都有一个prototype属性(指针,其指向函数的原型对象);该属性的值是一个对象,我们管它叫原型对象,其实它就是一个普通对象。对象该有的他都有。它还有个特殊的属性--constructor。属性值就是前面的函数。

关系图:

当调用构造函数创建实例时,实例内部将包含一个属性(指向其构造函数的原型对象的指针),在chrome、ff。这个属性是__proto__。这个属性的值是其构造函数的原型对象。

如上所示,obj是Object构造函数的一个实例,实例上有__proto__属性。这个属性值全等于Object构造函数的原型对象。

多亏有这个__proto__指针,我们在某构造函数的原型对象上定义的属性和方法都能被其所有的实例所共享。

在一些浏览器里(没错,就是IE),这个指针是不可见的。我们可以用 isPrototypeof()方法或者Object.getPrototypeOf()方法来判断实例与原型之间是否存在这种关系。

IE9以下就不支持Object.getPrototypeOf()方法了。

如果实例的 __proto__属性 或者叫 指向构造函数原型对象的指针 指向调用isPrototypeOf()方法的对象(Fn.prototype)。那么这个方法返回值是true。

这里一定要理解,实例的__proto__属性或者叫指向构造函数原型对象的指针是实实在在存在的,只不过有些浏览器给他取了个名字__proto__。有些浏览器没有去定义这个指针的名字。

Object.getPrototypeOf(fn1)方法返回的对象是fn1的构造函数的原型对象。

接下来就是原型链了

在js里。Object类型是基础类型,其他所有的引用类型都继承这个类型。

那么要怎么实现继承呢。

JS实现继承的方式主要就是通过原型链方法。

前面学习时,我们已经得知每个构造函数都有一个原型对象,构造函数的实例有一个指向原型对象的指针。

我们要做的就是。

把另外一个构造函数的实例赋值给原型对象。

首先,我们再定义一个函数Foo,此时Foo.prototype.__proto__ 全等于 Object.prototype;

(原型对象也是对象,自然也会有__proto__指针,如果没有去改它。默认就是指向Object.prototype呦)

接着。把另外一个构造函数的实例赋值给Foo.prototype。

显而易见,根据引用类型值的特性,Foo.prototype 和 fn1指向同一个对象。

这个对象的__proto__属性又指向其构造函数的原型对象。由此Foo函数的原型对象就包含了指向Fn的原型对象的指针。

即:Foo.prototype.__proto__ === Fn.prototype。

如果Fn的原型对象也是另外另外一个函数的实例。。。上述关系仍然成立,如此层层递进。一直指到Object.prototype。

这个对象就比较特殊了。它就没有__proto__属性。Object.prototype.__proto__ === null。原型链到此结束。

上图:

以上定义了两个函数。Person是超类型,Teacher子类型。人可以不是老师,但是老师一定是人嘛。哈哈哈。

属性的继承是通过

构造函数的this指向他的实例。通过call方法。把Person函数的this绑定到Teacher的实例xm,xh上。相当于xm.name = ‘小明‘;xh.name = ’小花‘;

方法的继承通过

这步实现了原型链关系。通过向原型链查找,只要存在于原型链上的方法,实例都能用。

确定原型和实例的关系

除了上面的isPrototypeOf()方法外,还有一个方法广为人知。就是使用Instance of 。

用这个操作符测试实例和原型链中出现过的构造函数。结果会返回true。

实现一个简单的instanceof操作符。

1.

1 Object.prototype.myInstanceOf = function (Func) {
2   if (typeof Func !== ‘function‘) {
3     return false;
4   }
5   return Func.prototype.isPrototypeOf(this);
6 };

2.

 1 Object.prototype.myInstanceOf = function (Func) {
 2   if (typeof Func !== ‘function‘) return false;
 3
 4   function _fn(instance, Func) {
 5     if (instance.__proto__) {
 6       if (instance.__proto__ !== Func.prototype) {
 7         return _fn(instance.__proto__, Func);
 8       } else {
 9         return true;
10       }
11     }
12     return false;
13   }
14   return _fn(this, Func);
15 };

3.

Object.prototype.myInstanceOf = function (Func) {
  if (typeof Func !== ‘function‘) {
    return false;
  }
  let _obj = Object.getPrototypeOf(this),
      res = false;
  while (_obj) {
    if (_obj === Func.prototype) {
      res = true;
      break;
    }
    _obj = Object.getPrototypeOf(_obj);
  }
  return res;
};

结果:

也不知道有没有什么边界情况下的错误。。。

累死了。。

原文地址:https://www.cnblogs.com/caimuguodexiaohongmao/p/11134741.html

时间: 2024-10-10 10:10:35

javascript原型原型链 学习随笔的相关文章

Javascript的原型链图

90%的前端或者js程序员或者老师们对Javascript懂得不比这个多 给手机看的 但是这个图里的所有褐色单向箭头链就是Javascript的原型链(颜色标注对理解js原型链很关键) 这图中的各个__proto__ constructor .prototype 都是内部对象 这样画是为了简洁 举个例子 如果考虑__proto__ 作为内部对象 上图变为 原型链就是 constructor 和 prototype如果作为内部对象 放到相应的位置 图就变大麻团了 保证晕倒什么也记不住 不服请看 这

浅谈javascript的原型及原型链

浅谈javascript的原型及原型链 这里,我们列出原型的几个概念,如下: prototype属性 [[prototype]] __proto__ prototype属性 只要创建了一个函数,就会为该函数创建一个prototype属性,指向该函数的原型对象.实例对象是不会拥有该属性的.默认情况下,该原型对象也会获得一个constructor属性,该属性包含一个指针,指向prototype属性所在的函数. Person.prototype.constructor===Person [[proto

Javascript的原型和原型链

prototype :每个函数都会有这个属性,这里强调,是函数,普通对象是没有这个属性的(这里为什么说普通对象呢,因为JS里面,一切皆为对象,所以这里的普通对象不包括函数对象).它是构造函数的原型对象: __proto__ :每个对象都有这个属性,,这里强调,是对象,同样,因为函数也是对象,所以函数也有这个属性.它指向构造函数的原型对象: constructor :这是原型对象上的一个指向构造函数的属性 创建对象的三种方式 通过对象直接量 通过对象直接量创建对象,这是最简单也是最常用的创建对象的

JavaScript原型&原型链

原型&原型对象 先来一段简单的代码: function Fun(name) { this.name = name } var obj = new Fun('obj') JavaScript中的对象都有一个[[Prototype]]内置属性(即部分浏览器实现的__proto__属性),这是一个访问器属性,通过这个可以访问对象的[[Prototype]]:对象就是以这个属性为模板,来"继承"方法和属性. JavaScript中的方法都有一个prototype属性,有一个constr

JavaScript ES5类 原型 原型链 组合、原型、寄生式继承

ES5类 原型  原型链 继承 JavaScript中,原型是相对于构造函数(类)的叫法(或者说概念),原型链是相对于构造函数(类)的实例对象的叫法. 对于JavaScript对象,如果在对象自身上找不到该属性,那么就会向上沿着原型链继续查找该属性 创建一个ES5类 在ES5中,类是由函数名首字母大写的函数,通过关键字new创建的. 类的构造函数就是函数自身 一般情况下,ES5类的原型对象prototype是自身构造函数,该类的实例化对象的原型链对象__proto__也是该构造函数,这二者指向同

深入理解javascript之原型

理解原型 原型是一个对象,其他对象可以通过它实现属性继承.任何一个对象都可以成为继承,所有对象在默认的情况下都有一个原型,因为原型本身也是对象,所以每个原型自身又有一个原型.任何一个对象都有一个prototype的属性,记为:__proto__.每当我们定义一个对象,其__proto__属性就指向了其prototype.示例如下: var foo = { x: 10, y: 20 }; 即使我们不指定prototype,该属性也会预留.如果我们有明确指向的话,那么链表就连起来了.需要注意的是,p

JavaScript之原型深入详解

理解原型 原型是一个对象,其他对象可以通过它实现属性继承.任何一个对象都可以成为继承,所有对象在默认的情况下都有一个原型,因为原型本身也是对象,所以每个原型自身又有一个原型.任何一个对象都有一个prototype的属性,记为:__proto__.每当我们定义一个对象,其__proto__属性就指向了其prototype.示例如下: var foo = { x: 10, y: 20 }; 即使我们不指定prototype,该属性也会预留.如果我们有明确指向的话,那么链表就连起来了.需要注意的是,p

JavaScirpt中的原型,原型对象和原型链

一.什么是原型呢? 我们创建每一个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象.(即prototype即为函数的原型该原型指向的是一个原型对象) 二.什么是原型对象呢? 我们创建每一个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象(即原型对象).而这个对象的用途是包含 可以由特定类型的所有 实例 共享的属性和方法.(字面意思prototype就是通过调用构造函数而创建的实例对象的原型对象) 使用原型对象的好处是可以让所有的对象实例(实

史上最清晰的JavaScript的原型讲解

一说起JavaScript就要谈的几个问题,原型就是其中的一个.说了句大话,史上最清晰.本来是想按照大纲式的行文写一下,但写到后边感觉其实就一个概念,没有什么条理性,所以下面就简单按照概念解释的模式谈下这个问题. 1.JavaScript的原型是什么? 原型,首先他是个对象.和在以对象为核心的JavaScript这门语言中的其他普通对象来说一样,只不过他的角色有点特殊.但首先要明白他就是一个对象,是一个无序的属性和值的序列对. 2.谁会具有原型这个对象? 所有的对象(包括函数这个对象)在默认的情