JS 原型与原型链问题集锦

想知道自己Js原型与原型链掌握的怎么样?来做个题试试吧!

Js原型与原型链图示:

Js原型与原型链图示

问题集锦:

问题1:

var A = function() {};
A.prototype.n = 1;
var b = new A();
A.prototype = {
n: 2,
m: 3
}
var c = new A();

console.log(b.n);
console.log(b.m);

console.log(c.n);
console.log(c.m);

答案1:

b.n -> 1
b.m -> undefined;

c.n -> 2;
c.m -> 3;

问题2:

var F = function() {};

Object.prototype.a = function() {
console.log('a');
};

Function.prototype.b = function() {
console.log('b');
}

var f = new F();

f.a();
f.b();

F.a();
F.b();

答案2:

f.a() -> a
f.b() -> f.b is not a function

F.a() -> a
F.b() -> b

问题3:

function Person(name) {
this.name = name
}
let p = new Person('Tom');

问题1: p.__proto__等于什么?

问题2:Person.__proto__等于什么?

答案3:

答案1:Person.prototype
答案2:Function.prototype

问题4:

var foo = {},
F = function(){};
Object.prototype.a = 'value a';
Function.prototype.b = 'value b';

console.log(foo.a);
console.log(foo.b);

console.log(F.a);
console.log(F.b);

答案4:

foo.a => value a
foo.b => undefined
F.a => value a
F.b => value b

问题5:

function Fn() {
var num = 500;
this.x = 100;
}
Fn.prototype.getX = function () {
console.log(this.x);
}
Fn.aaa = 1000;

var f = new Fn;

console.log(f.num)
console.log(f.aaa)
var res = Fn();
console.log(res)

答案5:

f.num => undefined
f.aaa => undefined
var res = Fn(); // res是undefined Fn中的this是window

问题6:一个灵魂面试题

function Person(name) {
this.name = name
}
var p2 = new Person('king');

// 核心点:__proto__是求原型对象的,也就是求构造器的prototype属性
// ===>原型对象是构造器的一个属性,本身是个对象

//constructor 是求构造器的 ====> 构造器的prototype属性的对象集合里也有constructor,
//这个prototype里的constructor指向构造器自己

console.log(p2.__proto__)//Person.prototype
console.log(p2.__proto__.__proto__)
//结合上题,也就是Person.prototype的__proto__,Person.prototype本身是个对象,
//所以这里输出:Object.prototype
console.log(p2.__proto__.__proto__.__proto__)
//同理,这里是求Object.prototype的__proto__,这里输出:null
console.log(p2.__proto__.__proto__.__proto__.__proto__)
//null后面没有了,报错
console.log(p2.__proto__.__proto__.__proto__.__proto__.__proto__)
//null后面没有了,报错

console.log(p2.constructor)//Person
console.log(p2.prototype)
//undefined p2是实例对象,不是函数对象,是没有prototype属性滴

console.log(Person.constructor)//Function 一个空函数
console.log(Person.prototype)
//打印出Person.prototype这个对象里所有的方法和属性

console.log(Person.prototype.constructor)//Person
console.log(Person.prototype.__proto__)
//Person.prototype是对象,所以输出:Object.prototype
console.log(Person.__proto__)//Function.prototype

console.log(Function.prototype.__proto__)//Object.prototype
console.log(Function.__proto__)//Function.prototype

console.log(Object.__proto__)//Function.prototype
console.log(Object.prototype.__proto__)//null

问题7:

function A() {
B = function () { console.log(10) }
return this
};
A.B = function () {
console.log(20)
};
A.prototype.B = function () {
console.log(30)
};
var B = function () {
console.log(40)
};
function B() {
console.log(50)
}

console.log(A.B()) // 20
console.log(B()) // 40
console.log(A().B()) // 10
console.log(B()) // 10
console.log(new A.B()) // 20
console.log(new A().B()) // 30

答案7解析:

A.B() // answer 20 【原型与原型链】
// 在`A`的原型对象中查找是否有`B`函数并且调用,这里并未执行`A`函数。
// A.B = function () {console.log(20)};
// 在A的原型对象中添加了`B`函数,停止查找,所以答案为 20

B() // answer 40 【函数表达式和函数声明】
// var B = function () {console.log(40)}
// function B() {console.log(50)}
// 同名 -> 函数提升会 > 变量提升
// 换言之 同名的函数表达式和函数声明同时存在时 总是执行表达式

A().B() // answer 10 【函数表达式和函数声明】
// A() 执行函数A ==> 1.变量B重新赋值函数 2.返回this(window)
// .B() 执行全局下的B函数 已经被重新赋值 所以输出10

B() // answer 10
// 上面的代码执行过A函数了,此时全局下的B函数输出10

new A.B() // answer 20【函数表达式和函数声明】
// new 执行了 A.B = function () {console.log(20)};

new A().B() // answer 30
// new 执行构造函数 A ,全局变量 B 重新赋值函数10
// 此时A() 指针指向哪里?
// 首先要知道 new 做了什么事?
// ==> 创建空对象objA objA.__proto__ = A.prototype
// .B() 在A的原型对象中查找 B; A.prototype 指向函数的原型对象
// A.prototype.B = function () {console.log(30)} 输出 30

未完待续。。。

Author: ahuiyoのblog
Link: http://ahuiyo.cn/prototype-problem/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
支付宝打赏
微信打赏