原型链学习(一)
//所有的对象都是通过new创建出来的
//所有的函数也是对象,所以函数中也可以有属性,
// 比如Array.isArray,Number.isNaN()
//所有对象都是引用类型
function test() {
return {}
}
console.log(new test())//构造函数是object
function test1() {
}
console.log(new test1())//构造函数是test1
console.log(typeof Array)//function
console.log(typeof String)//function
console.log(typeof Function)//function
console.log(typeof Number)//function
console.log(typeof Object)//function
console.log(typeof Boolean)//function
console.log(typeof null)//object
console.log(typeof test1)//function
//原型:所有函数都有一个属性:prototype,称之为函数原型
// 默认情况下,prototype是一个普通object对象,new 一个对象之后系统默认加上的
//默认情况下,prototype中有一个属性,constructor,他也是一个对象,指向构造函数本身
//隐式原型__proto__,所有对象都有隐式原型,
//隐式原型指向该对象的构造函数的prototype
// 特殊点
// 1.Function的隐式原型指向自身的prototype,即Function.prototype===Function.__proto__
// 2.Object的prototype的__proto__指向null
var obj=new test1();
console.log(obj.__proto__==test1.prototype)//test1返回的是函数,true
var obj1=new test();
console.log(obj1.__proto__==test.prototype)//test1返回的是一个对象,false
console.log(obj1.__proto__==Object.prototype)//test1返回的是一个对象,true
// 面试题
function A() {}
var a=new A();
var b=new A();
a.abc=123;
b.__proto__.bcd=456;
console.log(a.abc,b.abc)//123 undefined
console.log(a.__proto__.bcd,b.__proto__.bcd) // 456 456
//改一个对象的__proto__等同于修改该对象的构造函数的prototype,使用的是同一块地址空间
console.log(A.prototype.bcd)//456
//当访问的是一个对象的成员时,
// 1.如果有,则直接使用
// 2.如果该对象上面没有,就去隐式原型上面找(__proto__)
//3.如果还是没找到,就去原型链上一直找
//原型链上编程(猴子补丁):在函数原型中加入成员,以增强对象的功能,但是会导致原型链污染,使用需谨慎
String.prototype.camel=function () {
return this.replace(/\b(\w)(\w*)\b/g,function ($,$1,$2) {
return $1.toUpperCase()+$2
}).replace(/\s/g,"")
}
//面试题
var F=function () {}
Object.prototype.a=function () {}
Function.prototype.b=function () {}
var f=new F();
console.log(f.a,f.b,F.a,F.b)//fn undefined fn fn
//面试题
function A() {}
function B(a) {
this.a=a
}
function C(a) {
if(a){
this.a=a
}
}
A.prototype.a=1
B.prototype.a=1
C.prototype.a=1
console.log(new A().a)//1
console.log(new B().a)//undefined
console.log(new C().a)//2
//原型链最难面试
function User() {}
User.prototype.sayHello=function () {}
var u1=new User();
var u2=new User()
console.log(u1.sayHello===u2.sayHello)//true
console.log(User.prototype.constructor)//User
console.log(User.prototype===Function.prototype)//false
console.log(User.__proto__===Function.prototype)//true
console.log(User.__proto__===Function.__proto__)//true
console.log(u1.__proto__===u2.__proto__)//true
console.log(u1.__proto__===User.__proto__)//false
console.log(Function.__proto__===Object.__proto__)//true
console.log(Function.prototype.__proto__===Object.prototype.__proto__)//false
console.log(Function.prototype.__proto__==Object.prototype)//true
(完)