目录原型链我们来回顾一下什么是原型然后是原型链关于原型链一些有意思的东西最后是关于new关键字原型链 我们来回顾一下什么是原型 我们知道js中所有的对象、函数、数组都可以看成对象,也
所有的对象身上都有一个__proto__
属性,他叫隐式原型,指向了构造这个对象(如obj)的构造函数(例如Constructor)的原型对象即Constructor.prototype,也就是说obj.__proto__===Constructor.prototype
,这两个指针指向的其实是同一块堆空间
在构造函数的原型对象prototype(Constructor.prototype
)中,一般包含constructor
属性和__proto__
属性。
其中constructor
包含函数的一些信息如argments
、caller
、length
、name
和prototype指向构造函数的原型对象自身以及__scope__
即闭包属性(其中有函数需要使用的外部变量以及全局上下文,以伪数组的形式储存在scope闭包对象中),另外__proto__
的话,其实就是把Constructor.prototype
看成new
出来的对象实例,__proto__
就是指向Constructor.prototype
的构造函数(如Superconstructor
)的实例对象即Superconstructor.prototype
具体可以参照下图:
由于对象(如obj)的隐式原型(obj.__proto__
)指向构造函数的prototype
(如Constructor.prototype
),
而这个prototype
(如Constructor.prototype
)里面又有一个__proto__
,它指向了prototype
的构造函数的prototype
(如Superconstructor.prototype
),
然后Superconstructor.prototype.__proto__
指向了Object.prototype
这样就形成了一个简单的链式结构,这个条链的最后是Object.prototype.__proto__
为null
以上就是原型链的构成
原型链的使用
当你使用一个对象的属性或方法时,会先在该对象上查找已有属性,如果没有,就找到__proto__,找原型身上的属性,如果原型没有,那就再找原型的原型身上是否存在待查找属性,知道找到或者找到原型链的顶端null
我们知道typeof
可以用于判断变量的数据类型,但是对于复杂数据类型,它只能判断出对象、数组或函数,这对于我们的使用来说是不够的
所以我们可以用instanceof
来判断引用数据类型的对象类型
typeof A //'function'
obj instanceof A //true
obj instanceof Object //true
在使用时我发现一个有趣的问题
Function instanceof Object //true
Object instanceof Function //true
这是为什么呢?
我们尝试使用
Function.__proto__===Object.prototype //false
发现得到的是false,也就是Function并不是Object new出来的
但是尝试
Object.__proto__===Function.prototype //true
却发现Object是由Function new
出来的
接着我们分析一下instanceof
的工作原理, 我们尝试用函数instance_of来手写instanceof
关键字
function instance_of(L, R) {
var O = R.prototype;
L = L.__proto__;
while (true) {
if (L === null)
return false;
if (O === L)
return true;
L = L.__proto__;
}
}
对于以上代码分析,我们其实是在找左值的原型链上是否存在右值的原型
于是我们尝试
Function.__proto__===Function.prototype //true
Function.__proto__.__proto__===Object.prototype //true
发现原来Function.prototype
是由Object new
出来的,同时Function也是可以由自己new
出来
Function
由Function new出来
,Object
由Function new
出来,Function.prototype
由Object new
出来当代码 new Foo(...)
执行时,会发生以下事情:
Foo.prototype
的新对象被创建(类似于Object.create
)。Foo
,并将 this
绑定到新创建的对象。new Foo
不带括号就是没有指定参数列表,Foo
不带任何参数调用。new
表达式的结果。如果构造函数没有显式返回一个对象,则使用步骤 1 创建的对象。(一般情况下,构造函数不返回值,但是可以选择主动返回对象,来覆盖正常的对象创建步骤)尝试用newFun
手写new
关键字
function newFun(Constructor) {
var obj = {};
obj.__proto__ = Constructor.prototype;
return Constructor.apply(obj);
};
使用Object.create
function newFun() {
Constructor = [].shift.call(arguments);// 取出第一个参数Constructor
var obj = Object.create(Constructor);
return Constructor.apply(obj, arguments);// 使用参数调用
};
let a = {
k:10,
hh(){
console.log(this);
}
}
let b = {
k:9,
a
}
b.a.hh();
到此这篇关于javascript中Function与Object的关系的文章就介绍到这了,更多相关JavaScript Function Object内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: JavaScript中Function与Object的关系
本文链接: https://lsjlt.com/news/212371.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-01-12
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0