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)
	}
	
    A.B() // 20
	B() // 40
	A().B() // 10
	B() // 10
	new A.B() // 20
	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

未完待續。。。


自建博客地址:ahuiyo的博客:JS 原型與原型鏈問題集錦

發佈了57 篇原創文章 · 獲贊 64 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章