【JS】关于JS原型的一道题目
f
能取到a
,b
吗?原理是什么?
var F = function(){};Object.prototype.a = function(){};
Function.prototype.b = function(){};
var f = new F();
回答
f.a === Object.prototype.a //=> truef.b === Function.prototype.b //=> false
f 的原型链:
f -----> F.prototype -----> Object.prototype -----> null
F 的原型链:
F -----> Function.prototype -----> Object.prototype -----> null
f能取到a,b吗?
f能取到a,但取不到b
原理是什么?
一个对象能不能取得一个属性,首先在对象本身找,若本身没有就往上去它的原型对象里找,还没有就再往上一级原型对象里找,一直到root对象,就是Object或者Function。
针对这个题目中f,它是一个object (typeof f)
,它的原型对象是f.__proto__
,但f.__proto__
里面没有a和b,所以继续往上找,typeof f.__proto__
=>'object', f.__proto__.__proto__
=> Object{}, Object里面有a。
你可以验证一下f.__proto__.__proto__.hasOwnProperty('a')
== true
同理你可以在F里取到a和b。
var F = function(){};Object.prototype.a = function(){};
Function.prototype.b = function(){};
var f = new F();
f的原型链到Object.prototype结束
f->Object.prototype->没了
F为一个函数对象,同样也有原型链,其原型链的终点也是Object.prototype
F->Function.prototype->Object.prototype->没了
f(F的实例对象)能访问a
F(函数对象)能访问a,b
f
可以取到a
,F
可以取到a
,b
,可以看这个demo。
原因:a方法是添加在Object
上的,b
方法是添加在Function
上的,f
是一个Object
也是F
函数的引用,所以只可以取到a
,但是取不到b
;F
是Function
又是Object
所以两个都可以取到。
@此刻最好@fighterleslie@Chunwei 可以看下这个1楼回复http://segmentfault.com/q/1010000002736664
来自《Node.js 开发指南》
var F = function () { }; Object.prototype.a = function () {
console.log("a");
};
Function.prototype.b = function () {
console.log("b");
};
var f = new F();
//注意:对象的__proto__属性,指向对象的父级构造器的prototype原型
console.log(f);
console.log(f.__proto__); //F.prototype
console.log(F.prototype.__proto__); //Ojbect.prototype
console.log(Object.prototype.a()); //a
/****************************************************************/
console.log(f.constructor); //F
console.log(F.__proto__); //Function.prototype
console.log(Function.prototype.b()); //b
//结论:所有对象的__proto__都指向其构造器的prototype
//结论:所有构造器/函数的__proto__都指向Function.prototype,它是一个空函数(Empty function)
//结论:Function.prototype的__proto__最终指向Object.prototype
应该a b都可以访问吧
当然可以,Object是最顶级的,Object比Function还高一级,作为实例的f当然可以继承到a和b
很明显都可以啊,为什么和你们答案都不一样??
f.__proto__.__proto__.a()
f.constructor.constructor.b()
任何对象可以通过__proto__指到Object{}再指向null;任何函数通过constructor指向Function(),Function()的constructor是自己
var F = function(){};
Object.prototype.a = function(){console.log("this is a")};
Function.prototype.b = function(){console.log("this is b")};
var f = new F();
f.__proto__.__proto__.a();
f.constructor.constructor.b();
VM1230:3 this is a
VM1230:4 this is b
问题1:是的,f能取到a,b.
方式:
a:f.a
b:f.constructor.b
问题2:
取a原理:js一切皆对象,所有的对象都是(直接或间接)Object的实例,所以f能获取到Object.prototype上的属性。
取b原理:js中所有的实例都有一个属性constructor指向其构造函数。此处:f的构造函数是F,即:f.constructor即是F,所以f.constructor.b可以取到b。
美中不足的是f.constructor.b执行环境(this所指)不是f,当然可以改回来(利用call/apply/bind),如:f.constructor.b.call(f)
通过构造函数new出来的f是一个对象,所以它是在object链上,能访问到object的原型属性a。F是构造函数,其本身就是函数,,所以能访问到整个function的链,但同时最顶层function又被指向object,所以又能访问到object,所以F能访问到a,b。这样应该最直白吧
题目:
var F = function(){};Object.prototype.a = function(){};
Function.prototype.b = function(){};
var f = new F();
先放结果:能调用到a,不能调用b
分析:
原型链问题,我们首先从F函数上分析,
F.prototype => Object.prototype => null
实例化f的原型链是没有包括Function,prototype的,如想两个方法都能调用到,可以修改原型链F.prototype = new Function;
即可。
存在F.b F.a f.a
f.b不存在
以上是 【JS】关于JS原型的一道题目 的全部内容, 来源链接: utcz.com/a/82734.html