原型链学习(一)

 
 
 
 
 
 
 
   //所有的对象都是通过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

 (完)

posted @ 2019-09-21 15:30  bestupid  阅读(185)  评论(0编辑  收藏  举报