Skip to main content

moregeek program

javascript原型和原型链_程序猿布欧的博客-多极客编程

前言


在了解原型和原型链之前,我们先了解一部分概念,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原型和原型链


源码地址


欢迎关注公众号:程序员布欧,不定期更新一些文章


创作不易,转载请注明出处和作者。

©著作权归作者所有:来自51CTO博客作者程序员布欧的原创作品,请联系作者获取转载授权,否则将追究法律责任
javaScript原型和原型链
https://blog.51cto.com/u_15614290/5426205

#yyds干货盘点# 【react工作记录六十六】ant design row col样式修改_前端歌谣的博客-多极客编程

 前言我是歌谣 我有个兄弟 巅峰的时候排名c站总榜19 叫前端小歌谣 曾经我花了三年的时间创作了他 现在我要用五年的时间超越他 今天又是接近兄弟的一天人生难免坎坷 大不了从头再来 歌谣的意志是永恒的 放弃很容易 但是坚持一定很酷导语ant design Row col样式修改​编辑<Card><Row gutter={24}><Col span={3}><

日拱算法:只出现一次的数字_安东尼漫长的技术岁月的博客-多极客编程

突一突 ​​LeetBook 列表​​/算法面试题汇总冲冲冲~~题目:### 只出现一次的数字给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。说明:你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?示例 1:输入: [2,2,1]输出: 1示例 2:输入: [4,1,2,1,2]输出: 4解:第一个反应用 map 来解,时间复杂度

js class 并不只是简单的语法糖!_安东尼漫长的技术岁月的博客-多极客编程

在很早以前,写过一篇文章 “类”设计模式和“原型”设计模式——“复制”和“委托”的差异 ,大致意思就是说:代码复用,也就是继承、重写,有两种思路:1. 面向对象的类继承;2. 基于 JavaScript 原型链的原型继承;前者的主要特点是:复制,通俗来说就是把变量、属性再复制一份,后者的主要特点是:委托,通过属性的查找来实现的。后来呢,深入了解 JavaScript 高级程序设计中的继承,包括构造

日拱算法:多数元素_安东尼漫长的技术岁月的博客-多极客编程

突一突 ​​LeetBook 列表​​/算法面试题汇总冲冲冲~~题目:### 多数元素给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。你可以假设数组是非空的,并且给定的数组总是存在多数元素。  示例 1:输入: nums = [3,2,3]输出: 3示例 2:输入: nums = [2,2,1,1,1,2,2]输出: 2提示:

javascript扩展原型链浅析_程序猿布欧的博客-多极客编程

前言 上文对原型和原型链做了一些简单的概念介绍和解析,本文将浅析一些原型链的扩展。 javaScript原型和原型链http://lewyon.xyz/prototype.html 扩展原型链 使用new操作符 利用原型是对象的特性,实例化对象的时候,继承多个构造函数的属性和方法 兼容性:支持目前以及所有可想象到的浏览器 (IE5.5 都可以使用) function parent1() {}

#yyds干货盘点# 【react工作记录六十七】前端实现复制文字操作_前端歌谣的博客-多极客编程

 前言我是歌谣 我有个兄弟 巅峰的时候排名c站总榜19 叫前端小歌谣 曾经我花了三年的时间创作了他 现在我要用五年的时间超越他 今天又是接近兄弟的一天人生难免坎坷 大不了从头再来 歌谣的意志是永恒的 放弃很容易 但是坚持一定很酷导语前端实现复制文字操作​编辑 核心代码copyTitle(certB64) {let oInput = document.createElement('input');o

#yyds干货盘点# 【react工作记录六十六】ant design row col样式修改_前端歌谣的博客-多极客编程

 前言我是歌谣 我有个兄弟 巅峰的时候排名c站总榜19 叫前端小歌谣 曾经我花了三年的时间创作了他 现在我要用五年的时间超越他 今天又是接近兄弟的一天人生难免坎坷 大不了从头再来 歌谣的意志是永恒的 放弃很容易 但是坚持一定很酷导语ant design Row col样式修改​编辑<Card><Row gutter={24}><Col span={3}><

夏天来啦,用纯css实现水果解解馋吧_南城前端的博客-多极客编程

今日是农历六月初一。不知不觉地又是一年夏天来临了,面对烈日炎炎,夏天要吃的水果那是必不可少,今天就用CSS来给大家带来一个水果拼盘,提前给大家解解暑~ 前言 以上15种水果你能看出都是什么水果吗?相对不够那么逼真,但是相信你也能猜出大概的名称。接下来将分别展开代码说明各自的实现过程,在不看下文的代码前可以先思考一下看到以上图片你会用什么方式去实现呢? 为保障文章的精华部分,部分非主要代码就不完整

日拱算法:只出现一次的数字_安东尼漫长的技术岁月的博客-多极客编程

突一突 ​​LeetBook 列表​​/算法面试题汇总冲冲冲~~题目:### 只出现一次的数字给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。说明:你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?示例 1:输入: [2,2,1]输出: 1示例 2:输入: [4,1,2,1,2]输出: 4解:第一个反应用 map 来解,时间复杂度

「node学习笔记」node.js的buffer模块详解_wx612751f2ed44d的博客-多极客编程

在 Node.js 中提供了 Buffer 类,通过 Buffer 类中的各种构造函数创建 Buffer 对象,从而实现将缓存区中的字节数据转换为字符串对象以及将缓存区中的字节数据与数值对象之间进行转换。​一、如何创建Buffer类的实例​node.js 中的 Buffer 类是一个全局类,使用时不需要引入可直接使用,在 nodejs 中,Buffer 的创建可以分为两种:​1、在 Node 6.

交友平台小程序制作开发代码分享_it跟班的博客-多极客编程

这个是目前比较常见的婚恋交友平台小程序制作开发代码案例解析,很多功能大家都可以参考借鉴,比如关注功能,会员付费功能,权限设置等功能。首页部分class DiaryController extends CommonController{ private $weather = array("请选择","晴天","阴天","多云","雨天","雷阵雨","雪天"); private $feel =

日拱算法:多数元素_安东尼漫长的技术岁月的博客-多极客编程

突一突 ​​LeetBook 列表​​/算法面试题汇总冲冲冲~~题目:### 多数元素给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。你可以假设数组是非空的,并且给定的数组总是存在多数元素。  示例 1:输入: nums = [3,2,3]输出: 3示例 2:输入: nums = [2,2,1,1,1,2,2]输出: 2提示: