浅谈js原型
前言
突发奇想,想写一篇原型的文章,也可能是因为对原型有更深的理解吧,在这里做个记录,来记录下自己的理解加深下记忆。
总之,希望本文的内容能够对您的学习或者工作有所帮助。另,如果有任何的错误或者不足请指正!
创建对象有几种方法
js里说到原型,肯定离不开面向对象,说到面向对象肯定离不开对象,本文总结了大致3种创建对象的方法
字面量创建
显式的构造函数创建
使用Object.create()创建
原型、构造函数、实例、原型链
原型:函数都有prototype属性,是js默认添加的,prototype指向构造函数的原型对象,只有当函数是构造函数的时候,prototype才有意义
实例:只要是一个对象,都是实例
构造函数:构造函数是可以使用new运算符生成一个实例的函数就是构造函数,任何一个函数,只要被new使用了,都是构造函数
ps:原型有个构造器:constructor(构造器),指向是声明的构造函数
总结:
构造函数通过new和实例关联
构造函数通过prototype和原型对象关联
实例通过__proto__和原型对象关联
原型链是通过__proto__和prototype实现
Object.prototype是原型链的顶端
先有鸡还是先有蛋??
弄懂了上面那些,我们来看看一个有趣的现像
Function instanceof Object // true
Object instanceof Function // true
回答这个问题前,我们需要了解一下Function.protype,因为它是导致Function instanceof Object和Object instanceof Function都为true的根本原因。
Function.prototype是个不同于一般函数对象。
- Function.prototype像普通函数一样可以调用,但总是返回undefined;
- 普通函数实际上是Function的实例
Object本身就是一个构造函数,是Function的实例,即Object.__proto__就是Function.prototype
我们通过代码来了解一下:
// 1.Function的构造器是它自身
Function.constructor=== Function; //true
// 2.Object的构造器是Function(实际上所有函数的构造器都指向Function)
Object.constructor === Function; //true
// 3.Object的__proto__指向Function的prototype
Object.__proto__ === Function.prototype; //true
// 4.Function的__proto__指向Function的prototype
Function.__proto__ === Function.prototype //true
// 5.Function.prototype的__proto__指向Object.protype
Function.__proto__.__proto__ === Object.prototype //true
O(∩_∩)O,通过这里,我想大概我们可以知道为什么会有这个神奇的现像了吧?
是谁创建了它(Object.prototype)呢??
Object.prototype.__proto__===null //true
从这里可知,是null创造了一切,正如道德经所说:道生一,一生二,二生三,三生万物
instanceof的原理
我们再回过头来看先有鸡还是先有蛋的那个问题,造成这个现像的原因还是得归根于instanceof的运算规则。
instanceof的运算规则
w3c官方解释(传送门),还是一如既往的难懂 (lll¬ω¬)
我们用个简单的例子说明一下:
var Person = function (){}
var Student = function (){}
Student.prototype = new Person;
var gating = new Student()
gating instanceof Student //true
gating instanceof Person //true
ps: instanceof会递归查找左边的原型链
总结:instanceof检测左侧的__proto__原型链上是否存在右侧的原型对象。
new运算符
从上我们可以了解到原型、构造函数、实例、原型链了,接下来了解下new运算符
说到new运算符,我们先看看下面这段代码:
function Person(name){
this.name = name
}
var gating = new Person("gating")
很简单的一段代码,我们来看看new运算符是如何进行工作的呢?
我们可以把它拆分成3步:
创建一个新的对象,他继承于Person.prototype
构造函数Person被执行。相应的参数会被传入,同时this会指向这个新创建的对象。 tips:再不传递任何参数的情况下,new Person 等同于 new Person()
如果构造函数返回了一个“对象”,那么这个对象会取代整个new出来的结果。如果构造函数没有返回对象(通常也是这么做的, 不让其有返回值),那么new出来的结果为步骤1创建的对象
我们简单的通过代码实现一下new:
var new2 = function(fun){
var obj = Object.create(fun.prototype);
var o = fun.call(obj)
if(typeof o === 'object'){
return o
}else{
return obj
}
}
var Student = function (){}
var gating = new2(Student)
gating instanceof Student //true
最后,感谢各位观众老爷观看
浅谈js原型的更多相关文章
- 浅谈Js原型的理解
一.js中的原型毫无疑问一个难点,学习如果不深入很容易就晕了! 在参考了多方面的资料后,发现解释都太过专业,对于很多还没有接触过面向对象 语言的小白来说,有理解不了里面的专有名词!如果你没 ...
- 37.js----浅谈js原型的理解
浅谈Js原型的理解 一.js中的原型毫无疑问一个难点,学习如果不深入很容易就晕了! 在参考了多方面的资料后,发现解释都太过专业,对于很多还没有接触过面向对象 语言的小白来说,有理解不了里面 ...
- 浅谈JS中的!=、== 、!==、===的用法和区别 JS中Null与Undefined的区别 读取XML文件 获取路径的方式 C#中Cookie,Session,Application的用法与区别? c#反射 抽象工厂
浅谈JS中的!=.== .!==.===的用法和区别 var num = 1; var str = '1'; var test = 1; test == num //tr ...
- 浅谈JS之AJAX
0x00:什么是Ajax? Ajax是Asynchronous Javascript And Xml 的缩写(异步javascript及xml),Ajax是使用javascript在浏览器后台操作HT ...
- 浅谈JS中的闭包
浅谈JS中的闭包 在介绍闭包之前,我先介绍点JS的基础知识,下面的基础知识会充分的帮助你理解闭包.那么接下来先看下变量的作用域. 变量的作用域 变量共有两种,一种为全局变量,一种为局部变量.那么全局变 ...
- 浅谈 js 正则字面量 与 new RegExp 执行效率
原文:浅谈 js 正则字面量 与 new RegExp 执行效率 前几天谈了正则匹配 js 字符串的问题:<js 正则学习小记之匹配字符串> 和 <js 正则学习小记之匹配字符串优化 ...
- 浅谈 js 字符串之神奇的转义
原文:浅谈 js 字符串之神奇的转义 字符串在js里是非常常用的,但是你真的了解它么?翻阅<MDN String>就可以了解它的常见用法了,开门见山的就让你了解了字符串是怎么回事. 'st ...
- 浅谈 js 正则之 test 方法
原文:浅谈 js 正则之 test 方法 其实我很少用这个,所以之前一直没注意这个问题,自从落叶那厮写了个变态的测试我才去看了下这东西.先来看个东西吧. var re = /\d/; console. ...
- 浅谈 js 数字格式类型
原文:浅谈 js 数字格式类型 很多人也许只知道 ,123.456,0xff 之类的数字格式.其实 js 格式还有很多数字格式类型,比如 1., .1 这样的,也有 .1e2 这样的. 可能有人说这是 ...
随机推荐
- 黑马程序员_毕向东_Java基础视频教程——位运算练习(随笔)
位运算(练习) 最有效率的方式算出 2乘以 8等于几 2 << 3 = 2 * 2^3 = 2 * 8 = 16 对于两个整数变量的值进行互换(不需要第三方变量) class Test { ...
- ql的python学习之路-day8
前言:本节主要学习的是函数的全局变量和局部变量以及递归 一.全局变量和局部变量 定义在函数外并且在函数头部的变量,叫做全局变量,全局变量在整个代码中都生效. 局部变量只在函数里生效,这个函数就叫做这个 ...
- 我找到了Dubbo源码的BUG,同事纷纷说我有点东西
点赞再看,养成习惯,微信搜索[三太子敖丙]关注这个互联网苟且偷生的工具人. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的 ...
- yum命令无效
无论执行任何yum命令都无效,弄了两个小时.主要的方案有: 方案1:yum clean all 并查询repo中是否有enabled=0: https://unix.stackexchange.com ...
- 04.PageNumberPagination分页
一.使用默认分页 1.settings 设置 REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.Pag ...
- JVM_双亲委派机制
双亲委派机制及作用 什么是双亲委派机制 当`.class`文件需要被加载时,它首先把这个任务委托给他的上级类加载器,层层往上委托,如果上级的类加载器没有加载过,自己才会去加载这个类. 源码分析 pro ...
- 51Nod栈
LYK有一个栈,众所周知的是这个数据结构的特性是后进先出的. LYK感觉这样子不太美妙,于是它决定在这个前提下将其改进,也就是说,每次插入元素时,可以在栈顶或者栈底插入,删除元素时,只能在栈顶删除.L ...
- MySQL知识-MySQL同版本多实例的配置
MySQL多实例的配置 1. 创建需要目录 [root@db01 ~]# rm -rf /data/330{7..9}/data/*[root@db01 ~]# rm -rf /binlog/330{ ...
- 如何下载xshell家庭版
xshell是一个强大的安全终端模拟软件,它支持SSH1, SSH2, 以及Microsoft Windows 平台的TELNET 协议,加上友好炫酷的操作界面,深受广大码农的喜爱,是后端开发程序猿操 ...
- 集合框架之ArrayList -Java
ArrayList 1.与数组的区别 如果要存放多个对象,可以使用数组,但是数组会有长度的限制,会出现不够用或者是浪费的情况. 为了解决数组的局限性引入了容器的概念,最常用的容器就是ArrayList ...