prototype初步认识

在学习JavaScript中,遇到了prototype,经过一番了解,知道它是可以进行动态扩展的

function Func(){};
var func1 = new Func;
console.log(func1.var1) //undefined
Func.prototype.var1 = "Func进行了扩展"
console.log(func1.var1) //Func进行了扩展

即最开始创建的函数Func并没有var1变量,但是我们可以进行扩展,并且让根据其创建的对象也有var1变量

函数有prototype属性,函数创建的对象没有

这个时候,尝试对var1变量进行扩展,但是居然报错了

function Func(){};
var func1 = new Func;
console.log(func1.var1) //undefined
Func.prototype.var1 = "Func进行了扩展"
console.log(func1.var1) //Func进行了扩展
console.log(Func.var1)
func1.prototype.var1 = "func1进行了扩展" //Uncaught TypeError: Cannot set properties of undefined (setting 'var1')

获得当前对象的属性

那我们现在有一个疑问:func1应该是有var1变量的,那上面报错意思是func1没有prototype属性/方法咯?我如何查看一个对象到底有没有这个属性呢?

我们知道,可以用in来查看对象是否有属性

function Func(){};
var func1 = new Func;
console.log(func1.var1) //undefined
Func.prototype.var1 = "Func进行了扩展"
console.log(func1.var1) //Func进行了扩展
console.log(Func.var1)
// func1.prototype.var1 = "func1进行了扩展" //Uncaught TypeError: Cannot set properties of undefined (setting 'var1')
console.log("var1" in func1) //true
console.log("prototype" in func1) //false

现在我们知道了,func1确实没有prototype属性/方法,那func1也就是函数创建的对象都不能扩展了吗?回答这个问题之前,我们还要明白一个问题,func1中的var1变量是自己的吗?怎么区分呢?

function Func(){};
var func1 = new Func;
console.log(func1.var1) //undefined
Func.prototype.var1 = "Func进行了扩展"
console.log(func1.var1) //Func进行了扩展
console.log(Func.var1)
// func1.prototype.var1 = "func1进行了扩展" //Uncaught TypeError: Cannot set properties of undefined (setting 'var1')
console.log("var1" in func1) //true
console.log("prototype" in func1) //false
console.log("-----接下来看hasOwnProperty函数-----")
func1.var2 = "func1自己的变量"
console.log(func1.hasOwnProperty("var2")) //true
console.log(func1.hasOwnProperty("var1")) //false

我们可以用hasOwnProperty函数来知道变量是不是扩展的了

父和子的扩展

这里我把Func当成父,把func1当成子来作为个人理解

function Func() { };
var func1 = new Func;
console.log(func1.var1) //undefined
Func.prototype.var1 = "Func进行了扩展"
console.log(func1.var1) //Func进行了扩展
console.log(Func.var1)
// func1.prototype.var1 = "func1进行了扩展" //Uncaught TypeError: Cannot set properties of undefined (setting 'var1')
console.log("var1" in func1) //true
console.log("prototype" in func1) //false
console.log("-----接下来看hasOwnProperty函数-----")
func1.var2 = "func1自己的变量"
console.log(func1.hasOwnProperty("var2")) //true
console.log(func1.hasOwnProperty("var1")) //false
console.log("-----接下来看proto-----")
console.log(Func.hasOwnProperty("__proto__")) //false
console.log(func1.hasOwnProperty("__proto__")) //false
console.log(func1.__proto__ === Func.prototype) // true
console.log(func1.__proto__ == Func.prototype) // true
console.log(func1.prototype == Func.prototype) // false
console.log(func1.__proto__.var1) //Func进行了扩展
console.log(func1.var1) //Func进行了扩展

这里可以看到func1本身没有__proto__属性,但是和Func的protype属性是一样的

子的proto和prototype的区别

到这里你肯定想问,对于子func1的__proto__和prototype有什么区别呢?

首先子func1并没有prototype属性

其实双下划线表示隐藏的,不太想让外界访问到,这么思考,父Func不仅创建了子func1,而且创建了子func2,这时候如果子func1通过__proto__修改了var1,那么父Func的var1跟着变化,并且func2的var1也会变化,但是如果func1直接修改var1,那么父Func和子func2的var1都不会变化

function Func() { };
var func1 = new Func;
console.log(func1.var1) //undefined
Func.prototype.var1 = "Func进行了扩展"
console.log(func1.var1) //Func进行了扩展
console.log(Func.var1)
// func1.prototype.var1 = "func1进行了扩展" //Uncaught TypeError: Cannot set properties of undefined (setting 'var1')
console.log("var1" in func1) //true
console.log("prototype" in func1) //false
console.log("-----接下来看hasOwnProperty函数-----")
func1.var2 = "func1自己的变量"
console.log(func1.hasOwnProperty("var2")) //true
console.log(func1.hasOwnProperty("var1")) //false
console.log("-----接下来看proto-----")
console.log(Func.hasOwnProperty("__proto__")) //false
console.log(func1.hasOwnProperty("__proto__")) //false
console.log(func1.__proto__ === Func.prototype) // true
console.log(func1.__proto__ == Func.prototype) // true
console.log(func1.prototype == Func.prototype) // false
console.log(func1.__proto__.var1) //Func进行了扩展
console.log(func1.var1) //Func进行了扩展
console.log("-----接下来看proto和prototype的区别-----")
func1.var1 = "func1进行了扩展"
console.log(func1.var1) //func1进行了扩展
console.log(Func.prototype.var1) //Func进行了扩展

扩展得到的东西到底从哪来的

那么子func1我们前面使用了hasOwnProperty属性,但是func1本身并没有这个属性,那么它从哪来的?

function Func() { };
var func1 = new Func;
console.log(func1.var1) //undefined
Func.prototype.var1 = "Func进行了扩展"
console.log(func1.var1) //Func进行了扩展
console.log(Func.var1)
// func1.prototype.var1 = "func1进行了扩展" //Uncaught TypeError: Cannot set properties of undefined (setting 'var1')
console.log("var1" in func1) //true
console.log("prototype" in func1) //false
console.log("-----接下来看hasOwnProperty函数-----")
func1.var2 = "func1自己的变量"
console.log(func1.hasOwnProperty("var2")) //true
console.log(func1.hasOwnProperty("var1")) //false
console.log("-----接下来看proto-----")
console.log(Func.hasOwnProperty("__proto__")) //false
console.log(func1.hasOwnProperty("__proto__")) //false
console.log(func1.__proto__ === Func.prototype) // true
console.log(func1.__proto__ == Func.prototype) // true
console.log(func1.prototype == Func.prototype) // false
console.log(func1.__proto__.var1) //Func进行了扩展
console.log(func1.var1) //Func进行了扩展
console.log("-----接下来看proto和prototype的区别-----")
func1.var1 = "func1进行了扩展"
console.log(func1.var1) //func1进行了扩展
console.log(Func.prototype.var1) //Func进行了扩展
console.log("-----接下来看hasOwnProperty从哪来的-----")
console.log(Func.__proto__.__proto__.hasOwnProperty("hasOwnProperty")) // true
console.log(Func.__proto__.hasOwnProperty("hasOwnProperty")) // false
console.log(func1.__proto__.__proto__.hasOwnProperty("hasOwnProperty")) // true

父和子那节的那张图也可以看出,使用两次__proto__即可找到hasOwnProperty属性

那么到此也就了解了prototype和__proto__

附上完整代码两段供测试:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function Fun(){ }
var func1 = new Fun()
console.log(typeof Fun) // function
console.log(typeof func1) // object
console.log(func1.prototype) // undefined
console.log(typeof func1.__proto__) // object
console.log(func1.__proto__) // 一个比较复杂的object
console.log(func1.__proto__ == Fun.prototype) // true
console.log(func1.prototype == Fun.prototype) // false
Fun.prototype.var1 = "hello"
console.log(func1.var1) // hello
console.log(func1.__proto__.var1) // hello
func1.var1 = "yes"
console.log(Fun.var1) // undefined
console.log(func1.var1) // yes
console.log(Fun.prototype.var1) // hello
console.log(func1.__proto__.var1) // hello
console.log(func1.prototype) // undefined
func1.__proto__.var1 = "hhh"
console.log(func1.__proto__.var1) // hhh
console.log(Fun.prototype.var1) // hhh
console.log(Fun.__proto__.var1) // undefined
console.log("------测试原型对象里面的proto-------")
console.log(func1.hasOwnProperty("var1")) // true
console.log(func1.hasOwnProperty("__proto__"))
console.log(Fun.hasOwnProperty("hasOwnProperty")) // false
console.log(Fun.hasOwnProperty("__proto__")) // false
console.log(Fun.__proto__.__proto__.hasOwnProperty("hasOwnProperty")) // true
console.log(Fun.__proto__.hasOwnProperty("hasOwnProperty")) // false
console.log(func1.__proto__.__proto__.hasOwnProperty("hasOwnProperty")) // true
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function Func() { };
var func1 = new Func;
console.log(func1.var1) //undefined
Func.prototype.var1 = "Func进行了扩展"
console.log(func1.var1) //Func进行了扩展
console.log(Func.var1)
// func1.prototype.var1 = "func1进行了扩展" //Uncaught TypeError: Cannot set properties of undefined (setting 'var1')
console.log("var1" in func1) //true
console.log("prototype" in func1) //false
console.log("-----接下来看hasOwnProperty函数-----")
func1.var2 = "func1自己的变量"
console.log(func1.hasOwnProperty("var2")) //true
console.log(func1.hasOwnProperty("var1")) //false
console.log("-----接下来看proto-----")
console.log(Func.hasOwnProperty("__proto__")) //false
console.log(func1.hasOwnProperty("__proto__")) //false
console.log(func1.__proto__ === Func.prototype) // true
console.log(func1.__proto__ == Func.prototype) // true
console.log(func1.prototype == Func.prototype) // false
console.log(func1.__proto__.var1) //Func进行了扩展
console.log(func1.var1) //Func进行了扩展
console.log("-----接下来看proto和prototype的区别-----")
func1.var1 = "func1进行了扩展"
console.log(func1.var1) //func1进行了扩展
console.log(Func.prototype.var1) //Func进行了扩展
console.log("-----接下来看hasOwnProperty从哪来的-----")
console.log(Func.__proto__.__proto__.hasOwnProperty("hasOwnProperty")) // true
console.log(Func.__proto__.hasOwnProperty("hasOwnProperty")) // false
console.log(func1.__proto__.__proto__.hasOwnProperty("hasOwnProperty")) // true
</script>
</body>
</html>

一文彻底搞懂JavaScript中的prototype的更多相关文章

  1. 来一轮带注释的demo,彻底搞懂javascript中的replace函数

    javascript这门语言一直就像一位带着面纱的美女,总是看不清,摸不透,一直专注服务器端,也从来没有特别重视过,直到最近几年,javascript越来越重要,越来越通用.最近和前端走的比较近,借此 ...

  2. 帮你彻底搞懂JS中的prototype、__proto__与constructor(图解)

    作为一名前端工程师,必须搞懂JS中的prototype.__proto__与constructor属性,相信很多初学者对这些属性存在许多困惑,容易把它们混淆,本文旨在帮助大家理清它们之间的关系并彻底搞 ...

  3. 彻底搞懂JavaScript中的继承

    你应该知道,JavaScript是一门基于原型链的语言,而我们今天的主题 -- "继承"就和"原型链"这一概念息息相关.甚至可以说,所谓的"原型链&q ...

  4. 一文彻底搞懂Java中的环境变量

    一文搞懂Java环境变量 记得刚接触Java,第一件事就是配环境变量,作为一个初学者,只知道环境变量怎样配,在加上各种IDE使我们能方便的开发,而忽略了其本质的东西,只知其然不知其所以然,随着不断的深 ...

  5. 一张图搞懂 Javascript 中的原型链、prototype、__proto__的关系 转载加自己的总结

    1. JavaScript内置对象 所谓的内置对象 指的是:JavaScript本身就自己有的对象 可以直接拿来就用.例如Array String 等等.JavaScript一共有12内置对象    ...

  6. 彻底搞懂javascript中的match, exec的区别

    在工作中经常发现一些同学把这两个方法搞混,以致把自己弄的很郁闷.所以我和大家一起来探讨一下这两个方法的奥妙之处吧. 我们分以下几点来讲解: 相同点: 1.两个方法都是查找符合条件的匹配项,并以数组形式 ...

  7. 一分钟搞懂JavaScript中的JSON对象

    JSON(JavaScript Object Notation)是表示值和对象的通用格式. JavaScript 提供了如下方法: JSON.stringify 将对象转换为 JSON. JSON.p ...

  8. 来吧,一文彻底搞懂Java中的Comparable和Comparator

    大家好,我是沉默王二,今天在逛 programcreek 的时候,我发现了一些专注细节但价值连城的主题.比如说:Java 的 Comparable 和 Comparator 是兄弟俩吗?像这类灵魂拷问 ...

  9. 来吧,一文彻底搞懂Java中最特殊的存在——null

    没事的时候,我并不喜欢逛 P 站,而喜欢逛 programcreek 这些技术型网站,于是那天晚上,在夜深人静的时候,我就发现了一个专注基础但不容忽视的主题.比如说:Java 中的 null 到底是什 ...

随机推荐

  1. jdbc的快速入门(需要mysql-connector-java-5.1.39-bin.jar包)

    package Lianxi;import java.io.InputStream;import java.sql.Connection;import java.sql.DriverManager;i ...

  2. CAN总线系列讲座第五讲——CAN总线硬件电路设计

    CAN总线系列讲座第五讲--CAN总线硬件电路设计一  实战学习背景 CAN总线节点的硬件构成方案有两种,其中的方案:(1).MCU控制器+独立CAN控制器+CAN收发器.独立CAN控制器如SJA10 ...

  3. 数字电路的多路复用(MUX)

    学习文章:https://mp.weixin.qq.com/s/1pfLfvkAPyhEMLvfnyDy0g 最基本--2选1的MUX结构: 可以看作是:assign Y=S?B:A; 下面使用MUX ...

  4. 【控制】模型预测控制 MPC 【合集】Model Predictive Control

    1.模型预测控制--运动学模型 2.模型预测控制--模型线性化 3.模型预测控制--模型离散化 4.模型预测控制--预测 5.模型预测控制--控制律优化二次型优化 6.模型预测控制--反馈控制 7.模 ...

  5. Centos7 离线安装 KVM,并安装 Csr1000v

    最近需要在客户环境搭建 csr1000v,客户环境不能联网,同时使用 kvm 管理.所以需要离线安装 kvm,在利用 kvm 安装 csr100v ,中间遇到不少坑,现记录如下. 所有安装步骤是在 r ...

  6. 前端性能优化(Application Cache篇)

    正巧看到在送书,于是乎找了找自己博客上记录过的一些东西来及其无耻的蹭书了~~~ 小广告:更多内容可以看我的博客 之前在segmentfault上刷问题看到一个关于manifest的问题,很好奇就研究了 ...

  7. 《深入理解ES6》笔记—— Promise与异步编程(11)

    为什么要异步编程 我们在写前端代码时,经常会对dom做事件处理操作,比如点击.激活焦点.失去焦点等:再比如我们用ajax请求数据,使用回调函数获取返回值.这些都属于异步编程. 也许你已经大概知道Jav ...

  8. 微信小程序 使用filter过滤器几种方式

    由于微信小程序 技术生态比较闭合,导致很多 现代前端框架很多积累出的成果都没有实现(可能未来会逐一实现). 用惯了现代 再耍小程序 总感觉很不顺手. 需要结果的请直接看最后的WXS View Filt ...

  9. 前端学习02:jQuery 日历

    引言:学习前端已经接近1个月了,先后经历了1周的 html+css, 2周的"JavaScript 从入门到下跪",期间还看了vue+webpack.然鹅,Mentor Brigh ...

  10. vscode代码格式化快捷键及保存时自动格式化

    一.实现vs code中代码格式化快捷键:[Shift]+[Alt]+ F 二.实现保存时自动代码格式化: 1)文件 ------.>[首选项]---------->[设置]: 2)搜索  ...