一文详解JavaScript中prototype的使用

 更新时间:2022年05月11日 08:18:00   作者:lpzju  
这篇文章主要为大家详细介绍一下JavaScript中prototype的使用,文中的示例代码讲解详细,对我们学习有一定帮助,需要的可以参考一下

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的使用的详细内容,更多关于JavaScript prototype的资料请关注脚本之家其它相关文章!

相关文章

  • 10种JavaScript最常见的错误(小结)

    10种JavaScript最常见的错误(小结)

    这篇文章主要介绍了10种JavaScript最常见的错误(小结),查看了数千个项目后,发现了 10 个最常见的 JavaScript 错误。我们会告诉你什么原因导致了这些错误,以及如何防止这些错误发生
    2019-06-06
  • 让图片跳跃起来  javascript图片轮播特效

    让图片跳跃起来 javascript图片轮播特效

    让图片跳跃起来 这篇文章主要介绍了javascript图片轮播特效,图片按照间隔时间进行切换,文章具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • js实现文章目录索引导航(table of content)

    js实现文章目录索引导航(table of content)

    这篇文章主要介绍了js实现文章目录索引导航(table of content),需要的朋友可以参考下
    2020-05-05
  • javascript 中的继承实例详解

    javascript 中的继承实例详解

    这篇文章主要介绍了javascript 中的继承实例详解的相关资料,需要的朋友可以参考下
    2017-05-05
  • Webpack 之 babel-loader文件预处理器详解

    Webpack 之 babel-loader文件预处理器详解

    这篇文章主要介绍了Webpack 之 babel-loader文件预处理器详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-03-03
  • js onmousewheel事件多次触发问题解决方法

    js onmousewheel事件多次触发问题解决方法

    做一个首屏和第二屏之间滚动鼠标滚轮就可以整平切换的效果,遇到了很多问题,下面是问题解决方法
    2014-10-10
  • JS实现加载时锁定HTML页面元素的方法

    JS实现加载时锁定HTML页面元素的方法

    这篇文章主要介绍了JS实现加载时锁定HTML页面元素的方法,涉及javascript针对页面元素的遍历与属性操作相关实现技巧,需要的朋友可以参考下
    2017-06-06
  • js给图片打马赛克的方法示例

    js给图片打马赛克的方法示例

    有时候你发出去的图片局部不想别别人看见,那么最简单的办法就是在你想要处理的地方打上马赛克,这篇文章主要介绍了js给图片打马赛克的方法示例,感兴趣的可以了解一下
    2021-05-05
  • js经验分享 JavaScript反调试技巧

    js经验分享 JavaScript反调试技巧

    在这篇文章中,我打算跟大家总结一下关于JavaScript反调试技巧方面的内容。值得一提的是,其中有些方法已经被网络犯罪分子广泛应用到恶意软件之中了,需要的朋友可以参考下
    2018-03-03
  • JavaScript获取当前时间戳5种方法汇总

    JavaScript获取当前时间戳5种方法汇总

    很多时候我们都把时间戳作为id值,下面这篇文章主要给大家介绍了关于JavaScript获取当前时间戳的5种方法,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-10-10

最新评论