关键词:
前言
在了解原型和原型链之前,我们先了解一部分概念,constructor,prototype,proto。
constructor
在之前判断数据类型的文章: javaScript常见数据类型检查校验
有提到过关于构造函数的属性constructor
constructor 的是返回创建实例对象的 构造函数的引用,这个属性的值是对函数本身的引用,而不是一个包含函数名称的字符串
具体用法:构造函数.prototype.constructor()
function constructorFn()
this.name = "11";
console.log(constructorFn.constructor); // Function
let a = new constructorFn();
console.log(a.constructor);
// ƒ constructorFn()
this.name = "11";
原型prototype
console.log(Object.prototype);
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
constructor: ƒ Object()
hasOwnProperty: ƒ hasOwnProperty()
isPrototypeOf: ƒ isPrototypeOf()
propertyIsEnumerable: ƒ propertyIsEnumerable()
toLocaleString: ƒ toLocaleString()
toString: ƒ toString()
valueOf: ƒ valueOf()
__defineGetter__: ƒ __defineGetter__()
__defineSetter__: ƒ __defineSetter__()
__lookupGetter__: ƒ __lookupGetter__()
__lookupSetter__: ƒ __lookupSetter__()
__proto__: (...)
get __proto__: ƒ __proto__()
set __proto__: ƒ __proto__()
在js当中,每个函数或者方法都有一个特殊的,并且是默认的属性叫作原型(prototype),它是一个对象,这个对象包含了这个方法自带的一些属性和方法。
原型链 proto
function constructorFun()
constructorFun.prototype.testName = "constructorFun";
let newFun = new constructorFun();
// newFun
console.log(newFun);
console.log(newFun.testName); // 通过__proto__查找 输出: constructorFun
console.log(newFun.constructor); // ƒ constructorFun()
console.log(newFun.__proto__); // testName: constructorFun, constructor: ƒ
console.log(newFun.prototype); // undefined
console.log(newFun.prototype.__proto__); // Error in created hook: "TypeError: Cannot read property __proto__ of undefined"
通过上述代码我们可以看到,prototype这个对象里面,包含了一个proto的属性,这个属性就是原型链的关键,
-
当newFun用过new操作符,继承构造函数constructorFun的时候,testName,同时通过newFun.proto我们可以知道,newFun没有自己的name的时候,会通过proto不断地往上查找,直到查找到相关属性,如果不存在则为undefined
- 在JavaScript 中只有一种结构:对象。每个实例对象(object)都有一个私有属性(称之为 proto )指向它的构造函数的原型对象(prototype)。该原型对象也有一个自己的原型对象(proto),层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。(断言出自 MDN https://developer.mozilla.org/ )
从原型链查找到null的过程
构造函数
function constructorFun()
constructorFun.prototype.testName = "constructorFun";
let newFun = new constructorFun();
// newFun
console.log(newFun);
console.log(newFun.testName); // 通过__proto__查找 输出: constructorFun
console.log(newFun.constructor); // ƒ constructorFun()
console.log(newFun.__proto__); // testName: constructorFun, constructor: ƒ
console.log(newFun.prototype); // undefined
console.log(newFun.prototype.__proto__); // Error in created hook: "TypeError: Cannot read property __proto__ of undefined"
- 使用new操作符实例化的方法,没有自己的原型对象,并且通过proto可以向上查找构造函数的属性和方法,以及构造函数。
- 实例化方法可以通过constructor属性,获取构造函数本身
// constructorFun
console.log(constructorFun.constructor); // ƒ Function() [native code]
console.log(constructorFun.__proto__ === Function.prototype); // true
console.log(constructorFun.prototype); // testName: constructorFun, constructor: ƒtestName: "constructorFun"constructor: ƒ constructorFun()[[Prototype]] ...
console.log(constructorFun.prototype.constructor); // ƒ constructorFun()
console.log(constructorFun.prototype.__proto__ === Object.prototype); // true
- 构造函数constructorFun的属性constructor为Function,原型链向上查找的时候,构造函数的proto → Function的原型prtotype
- constructorFun的原型对象的proto是对象的原型
// Function
console.log(Function.constructor); // ƒ Function() [native code]
console.log(Function.__proto__); // ƒ () [native code]
console.log(Function.prototype); // ƒ () [native code]
console.log(Function.prototype.constructor); // ƒ Function() [native code]
console.log(Function.prototype.__proto__ === Object.prototype); // true
// Object
console.log(Object.constructor); // ƒ Function() [native code]
console.log(Object.__proto__); // ƒ () [native code]
console.log(Object.prototype); // constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …
console.log(Object.prototype.constructor); // ƒ Object() [native code]
console.log(Object.prototype.__proto__); // null
字面量创建对象
let parent = name:1
// parent
console.log(parent.constructor); // ƒ Object() [native code]
console.log(parent.__proto__); // constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …
console.log(parent.prototype); // undefined
// console.log(parent.prototype.__proto__); // Error in created hook: "TypeError: Cannot read property __proto__ of undefined"
// Object
console.log(Object.constructor); // ƒ Function() [native code]
console.log(Object.__proto__); // ƒ () [native code]
console.log(Object.prototype); // constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …
console.log(Object.prototype.constructor); // ƒ Object() [native code]
console.log(Object.prototype.__proto__); // null
通过以上代码查找,我们可以画出对应的关系图
总结:
- 原型prototype和原型链查找proto,constructor构成了原型链,通过这些属性和方法可以层层网上查找一直到null
- 构造函数实例化方法,可以通过原型链的形式向上查找到对应属性(这个属性存在的前提下),这里的知识点还包含了new实例的过程中,继承方面的知识
- 使用原型链和原型,我们可以进行封装一下构造方法,还有一些插件,我们在阅读一下框架源码或者插件源码的时候,都能看到原型和构造函数相关的代码。
- 原型和原型链的知识从概念上并不太好理解或者说有点晦涩难懂,可以试着去写一些实例化对象和方法,去查找原型上的方法
- 并且在开发过程中如果涉及到面向对象编程或者运用较多的话,可以加深我们的理解
- 类似数组以及Function等构造函数,我们可以通过继承,在原型链上扩展一些通用的utils方法
以上就是js中原型和原型链概念的简单解析,有任何问题欢迎留言,后续的文章整理然后作为补充。
文章博客地址:javaScript原型和原型链
源码地址
欢迎关注公众号:程序员布欧,不定期更新一些文章
创作不易,转载请注明出处和作者。
javascript之粗浅原型和原型链(代码片段)
目录1、示例代码2、注解1、示例代码functionStudent(params) this.params=params;letstudent=newStudent('159357');console.log(student.__proto__===Student.prototype);//trueconsole.log(student.co 查看详情
javascript原型和原型链(代码片段)
作用域链与原型链的区别作用域:作用域是针对变量的,比如创建了一个函数,函数里面又包含了一个函数,那么现在就有三个作用域全局作用域==>函数1作用域==>函数2作用域作用域的特点就是,先在自己的变量范围中查找... 查看详情
javascript高手之路:原型和原型链(代码片段)
原型和原型链是JavaScript进阶重要的概念,尤其在插件开发过程中是不能绕过的知识点,这篇文章就带你抽丝剥茧的学习这一过程。由一个例子开始说起在写博客过程中,我比较倾向和习惯从一个按例开始说起,以... 查看详情
原型和原型链的理解(代码片段)
原型链是一种机制,指的是JavaScript每个对象都有一个内置的 __proto__ 属性指向创建它的构造函数的 prototype(原型)属性。原型链的作用是为了实现对象的继承,要理解原型链,需要先从函数对象、constructor、new、protot... 查看详情
原型和原型链(代码片段)
...实例对象personprototype每个函数都有一个prototype属性每一个JavaScript对象(null除外)在创建的时候 查看详情
javascript的原型和原型链(代码片段)
概念: 当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__隐式原型上查找,即它的构造函数的prototype,如果还没有找到就会再在构造函数的prototype的__proto... 查看详情
浅谈javascript的原型和原型链(新手懵懂想学会原型链?看这篇文章就足够啦!!!)(代码片段)
💥本篇文章我将从概念和对应题目知识点讲起,希望大家能有所收获💥一、原型①所有引用类型都有一个_proto_(隐式原型)属性(类似链表中的next指针),链表可以通过.next访问下个元素,原型中可通过._proto_访... 查看详情
javascript原型和原型链(必考三座大三之一)(代码片段)
Class在学习原型和原型链之前,首先来说一下ES6诞生的新语法——class类,它是一个语法糖(就是更方便程序员使用的一种玩意),对比ES5,ES6中类的写法更加清晰、更像面向对象编程,一个类(构造函数... 查看详情
javascript原型链(代码片段)
javascript中原型以及原型链(代码片段)
js中原型以及原型链什么是原型对象每个函数身上都有一个原型,我们称之为原型对象函数的prototype属性指向原型对象,原型对象上的constructor指回构造函数废话少说,直接看代码functionPerson()this.uname='张三',th... 查看详情
认识了解原型原型链(代码片段)
什么是原型和原型链? Javascript只有一种结构,那就是:对象。在javaScript中,每个对象都有一个指向它的原型(prototype)对象的内部链接。这个原型对象又有自己的原型,直到某个对象(Object)的原型... 查看详情
javascript理解原型链(代码片段)
javascript原型继承原型链(代码片段)
...形成三、例-求以下代码的输出总结前言部分理论参考《JavaScript权威指南》每一个对象都有与之相关的原型(prototype),原型是在实例创建之初就设定好的,作用是继承属性.使用new调用构造函数会自动创建一个新对象,因此构造函数本... 查看详情
javascript原型链污染学习记录(代码片段)
NodeJS原型机制,比较官方的定义:我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。1.JS原型和继承机制0>原型及... 查看详情
[javascript]js原型链以及原型链继承(代码片段)
基础的三个要素:函数,函数实例,实例原型.实例原型相当于父类,函数相当于构造函数举例:classFnextendsFn.prototype实例:letf=newFn();Fn不能直接加方法或者属性,只能通过Fn.prototypef可以动态添加属性或者方法。如果f添加属性与Fn.prot... 查看详情
javascript学习笔记(代码片段)
Javascript学习笔记一、构造函数和原型1、概述2、构造函数1、利用构造函数创建对象2、静态成员和实例成员3、构造函数的问题4、构造函数原型prototype5、对象原型__proto__6、constructor构造函数7、构造函数、实例、原型对象三者之间... 查看详情
对象——原型与原型链(代码片段)
原型与原型链一.普通对象与函数对象JavaScript中,万物皆对象!但对象也是有区别的。分为普通对象和函数对象,Object、Function是JS自带的函数对象。下面举例说明varo1=;varo2=newObject();varo3=newf1();functionf1();varf2=function();varf3=newFunction(... 查看详情
javascript之彻底理解原型与原型链(代码片段)
1.前言原型与原型链知识历来都是面试中考察的重点,说难不算太难,但要完全理解还是得下一定的功夫。先来看一道面试题开开胃口吧:functionUser()User.prototype.sayHello=function()varu1=newUser();varu2=newUser();console.log... 查看详情