详解JavaScript中的原型和原型链

目录
  • 原型链图
  • 原型必备知识
  • prototype属性(显示原型)
  • proto属性(隐式原型)
  • constructor属性
  • 总结

原型链图

原型必备知识

要了解原型就必须搞清三个属性:__proto__prototype constructor

1.__proto__、 constructor属性是对象所独有的;

2.prototype属性是函数独有的;

3.js中函数也是对象的一种,那么函数同样也有属性__proto__、 constructor;

原型五大规则:

1.所有引用类型(对象,数组,函数)都具有对象特性,即可以自由扩展属性

2.所有引用类型(对象,数组,函数)都具有一个__proto__(隐式原型)属性,是一个普通对象

3.所有的函数都具有prototype(显式原型)属性,也是一个普通对象

4.所有引用类型(对象,数组,函数)__proto__值指向它构造函数的prototype

5.当试图得到一个对象的属性时,如果变量本身没有这个属性,则会去他的__proto__中去找

prototype属性(显示原型)

首先创建一个构造函数

var Parent = function(){
}
//定义一个函数,那它只是一个普通的函数
var p1 = new Parent();
//通过关键字new,Parent成为构造函数
//创建了一个Parent构造函数的实例 p1

prototype是函数独有的属性,通过这个属性就能访问到原型;

prototype设计之初就是为了实现继承,让由特定函数创建的所有实例共享属性和方法,也可以说是让某一个构造函数实例化的所有对象可以找到公共的方法和属性。有了prototype我们不需要为每一个实例创建重复的属性方法,而是将属性方法创建在构造函数的原型对象上(prototype)。那些不需要共享的才创建在构造函数中。

Parent是构造函数,Parent.prototype就是原型

Parent.prototype上添加的属性和方法叫做原型属性和原型方法,该构造函数的实例都可以访问调用。

proto属性(隐式原型)

__proto__属性是对象(包括函数)独有的。

每个对象都有__proto__属性,该属性指向的就是该对象的原型对象。

p1.__proto__ === Parent.prototype; // true

__proto__通常称为隐式原型,prototype通常称为显式原型,可以说一个对象的隐式原型指向了该对象的构造函数的显式原型。那么在显式原型上定义的属性方法,通过隐式原型传递给了构造函数的实例。这样一来实例就能很容易的访问到构造函数原型上的方法和属性了。

Parent.prototype的隐式原型指向了对象原型

Parent.prototype.__proto__ === Object.prototype; //true

这里引出原型链的概念,当调用p1.toString()的时候,先在p1对象本身寻找,没有找到则通过p1.__proto__找到了原型对象Parent.prototype,也没有找到,又通过Parent.prototype.__proto__找到了上一层原型对象Object.prototype。在这一层找到了toString方法。返回该方法供p1使用。

当然如果找到Object.prototype上也没找到,就在Object.prototype.__proto__中寻找,但是Object.prototype.__proto__ === null所以就返回undefined。这就是为什么当访问对象中一个不存在的属性时,返回undefined了。

constructor属性

既然构造函数通过 prototype 来访问到原型,那么原型也应该能够通过某种途径访问到构造函数,这就是 constructor。

如前面的例子p1就是一个对象,那p1的构造函数就是Parent()。Parent的构造函数是Function()

p1.constructor => f Parent{}
Parent.construtor => f Function() { [native code] }
Function.constructor => ƒ Function() { [native code] }

Function是所有函数的根构造函数。

通过例子可以看到,p1的constructor属性指向了Parent,那么Parent就是p1的构造函数。同样Parent的constructor属性指向了Function,那么Function就是Parent的构造函数,然后又验证了Function就是根构造函数。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • JS难点同步异步和作用域与闭包及原型和原型链详解

    目录 JS三座大山 同步异步 同步异步区别 作用域.闭包 函数作用域链 块作用域 闭包 闭包解决用var导致下标错误的问题 投票机 闭包两个面试题 原型.原型链 原型对象 原型链 完整原型链图 JS三座大山 同步异步 前端中只有两个操作是异步的: 定时器异步执行; ajax异步请求 编译器解析+执行代码原理: 1.编译器从上往下逐一解析代码 2.判断代码是同步还是异步 同步:立即执行 异步:不执行.放入事件队列池 3.等所有同步执行完毕开始执行异步 同步异步区别 api : 异步有回调,同步没有

  • 带你理解JavaScript 原型原型链

    目录 一.原型.原型链相等关系理解 二:原型.原型链的意思何在 看完这篇文章,你会发现,原型.原型链原来如此简单!  上面经典的原型链相等图,根据下文的学习,你会轻易掌握. 一.原型.原型链相等关系理解 首先我们要清楚明白两个概念: js分为函数对象和普通对象,每个对象都有__proto__属性,但是只有函数对象才有prototype属性 Object.Function都是js内置的函数, 类似的还有我们常用到的Array.RegExp.Date.Boolean.Number.String 这两

  • JavaScript 原型与原型链详情

    目录 1.prototype(显式原型) 2.__proto__(隐式原型) 3.constructor(构造函数) 4.new的原理 5.原型链 5.1 原型链的作用 5.2 构造函数的__proto__是什么呢? 6.总结 前言: JavaScript常被描述为一种「基于原型的语言」--每个对象都拥有一个「原型对象」,对象以其原型为模板.从原型继承属性和放法.原型对象也可能拥有原型,并从中继承属性和方法,一层一层以此类推.这种关系常被称为「原型链」,它解释了为何一个对象会拥有定义在其他对象中

  • 彻底理解JavaScript的原型与原型链

    目录 前言 基础铺垫 prototype contructor属性 __proto__ 原型链 提高 总结 后语 前言 原型与原型链知识历来都是面试中考察的重点,说难不算太难,但要完全理解还是得下一定的功夫.先来看一道面试题开开胃口吧: function User() {} User.prototype.sayHello = function() {} var u1 = new User(); var u2 = new User(); console.log(u1.sayHello === u2

  • 浅谈JS的原型和原型链

    1.原型prototype javascript中所有函数都具有这个属性,所有具有prototype属性的对象都是一个函数.prototype的作用是向对象添加一个方法/属性. function persion(){} persion.prototype.name = "xiaoming" console.log(persion.prototype)//{name: "xiaoming", constructor: ƒ} 2.原型指针:__proto__ 如果将上面

  • JavaScript原型链详解

    目录 1.构造函数和实例 2.属性Prototype 3.属性__proto__ 4.访问原型上的方法 5.构造函数也有__proto__ 6.构造函数的原型也有__proto__ 7.Object.prototype这个原型对象很特殊 8.总结 1.构造函数和实例 假设你声明一个方法叫做Foo() ,那么我们可以通过new Foo()来声明实例. function Foo() { console.log("我是一个构造方法"); } const f1 = new Foo(); 现在你

  • 全面解析js中的原型,原型对象,原型链

    理解原型 我们创建的每一个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法.看如下例子: function Person(){ } Person.prototype.name = 'ccc' Person.prototype.age = 18 Person.prototype.sayName = function (){ console.log(this.name); } var person1 = ne

  • 详解Javascript中prototype属性(推荐)

    在典型的面向对象的语言中,如java,都存在类(class)的概念,类就是对象的模板,对象就是类的实例.但是在Javascript语言体系中,是不存在类(Class)的概念的,javascript中不是基于'类的',而是通过构造函数(constructor)和原型链(prototype chains)实现的.但是在ES6中提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板.通过class关键字,可以定义类.基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能

  • 详解Javascript 中的 class、构造函数、工厂函数

    到了ES6时代,我们创建对象的手段又增加了,在不同的场景下我们可以选择不同的方法来建立.现在就主要有三种方法来构建对象,class关键字,构造函数,工厂函数.他们都是创建对象的手段,但是却又有不同的地方,平时开发时,也需要针对这不同来选择. 首先我们来看一下,这三种方法是怎样的 // class 关键字,ES6新特性 class ClassCar { drive () { console.log('Vroom!'); } } const car1 = new ClassCar(); consol

  • 详解JavaScript中的链式调用

    链模式 链模式是一种链式调用的方式,准确来说不属于通常定义的设计模式范畴,但链式调用是一种非常有用的代码构建技巧. 描述 链式调用在JavaScript语言中很常见,如jQuery.Promise等,都是使用的链式调用,当我们在调用同一对象多次其属性或方法的时候,我们需要多次书写对象进行.或()操作,链式调用是一种简化此过程的一种编码方式,使代码简洁.易读. 链式调用通常有以下几种实现方式,但是本质上相似,都是通过返回对象供之后进行调用. this的作用域链,jQuery的实现方式,通常链式调用

  • 详解JavaScript中new操作符的解析和实现

    前言 new 运算符是我们在用构造函数创建实例的时候使用的,本文来说一下 new 运算符的执行过程和如何自己实现一个类似 new 运算符的函数. new 运算符的运行过程 new 运算符的主要目的就是为我们创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例(比如箭头函数就没有构造函数,所以是不能 new 的).new 操作符的执行大概有以下几个步骤: 创建一个新的空对象 把新对象的 __proto__ 链接到构造函数的 prototype 对象(每一个用户定义函数都有一个 proto

  • 详解JavaScript中的数据类型,以及检测数据类型的方法

    一.js中的数据类型有哪些? 在js中,基本数据类型有五种,分别是 string.number.boolean.null.undefined,不过在ES6中新增加的了一种基本数据类型Symbol(表示独一无二的值),其作用主要是从根本上防止属性名的冲突而设定的. 除了基本数据类型之外,还有引用数据类型object,也有人称之为复杂数据类型,包含了我们常见的Array.Object.Function等. 所以现在js中的数据类型共有七种. PS: Symbol数据类型通过Symbol函数生成.也就

  • 详解JavaScript中哪一种循环最快呢

    了解哪一种 for 循环或迭代器适合我们的需求,防止我们犯下一些影响应用性能的低级错误. JavaScript 是 Web 开发领域的"常青树".无论是 JavaScript 框架(如 Node.js.React.Angular.Vue 等),还是原生 JavaScript,都拥有非常庞大的粉丝基础.我们来谈谈现代 JavaScript 吧.循环一直是大多数编程语言的重要组成部分,而现代 JavaScript 为我们提供了许多迭代或循环值的方法. 但问题在于,我们是否真的知道哪种循环或

  • 详解JavaScript中的4种类型识别方法

    具体内容如下: 1.typeof [输出]首字母小写的字符串形式 [功能] [a]可以识别标准类型(将Null识别为object) [b]不能识别具体的对象类型(Function除外) [实例] console.log(typeof "jerry");//"string" console.log(typeof 12);//"number" console.log(typeof true);//"boolean" console

  • 详解JavaScript 中getElementsByName在IE中的注意事项

    详解JavaScript 中getElementsByName在IE中的注意事项 前言: 在IE5-9中是没有实现js的 getElementsByClassName()方法,但是实现了getElementsByName()方法,但是需要注意的是这个方法在IE5-9中也返回id属性匹配的指定元素,为了兼容,应该小心谨慎使用,不要将同样的字符串同时用作了名字和ID. 测试程序如下: <div id="log"> <div id="innerLog"&

  • 详解JavaScript中的Object.is()与"==="运算符总结

    三重相等运算符 === 严格检查2个值是否相同: 1 === 1; // => true 1 === '1'; // => false 1 === true; // => false 但是,ES2015规范引入了 Object.is(),其行为与严格的相等运算符几乎相同: Object.is(1, 1); // => true Object.is(1, '1'); // => false Object.is(1, true); // => false 主要问题是:什么时

  • 详解JavaScript中的this指向问题

    题记 JS中的this指向一直是个让初学者头疼的问题.今天,我们就一起来瞅瞅this倒地是咋回事,详细说说this指向原则,从此不再为了this指向操碎了心. 开篇 首先我们都知道this是Javascript语言的一个关键字. 它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用.随着函数使用场合的不同,this的值会发生变化.但是有一个总的原则,那就是this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它所在函

随机推荐