面向对象的继承与原型链的概念

目录

一、面向对象的继承

二、原型链

三、原型链笔试题

1、如何判断自有还是共有属性?

2、如何为老版本IE添加indexOf方法?

3、如何判断一个对象是不是数组?

1)、判断xxx是不是继承自Array.prototype

2)、判断xxx是否由构造函数Array创建的

3)、ES5提供的一个方法

4)、输出对象的字符串形式


        我们在日常的编程中,用到了许多的方法,例如数组的常用方法字符串的常用方法等。但是当我们输出数字或者字符串等时,会发现其身上根本没有例如slice、concat的方法,那么这些方法保存在哪的呢?答案是:其父级构造函数身上。

一、面向对象的继承

什么是继承?

        继承就是父对象的成员(属性和方法),子对象能够随意使用。就好像在生活中,父亲的财产,自己的孩子可以进行继承等。

为什么要继承?

        简单的说就是:使代码能够进行重用,减少内存空间。

        当我们在构造函数中,定义一个方法时是怎样的?

function F1(){
    this.fun=function(){}
}

        当我们这样写的时候,每new一个实例化对象,就会在堆内存中创建一个函数,实例化一百个对象,就会创建一百个相同的函数。 这样长期下去,会导致内存不足,重复代码太多。

何时继承?

        只要是多个子对象都要使用的方法或者属性,都最好写在父对象身上。

JS中如何实现继承?

        答案是:通过原型链实现。

二、原型链

原型(prototype)的引出:

        原型,可以理解为:原本的类型。每一个对象都有自己的父亲,也就是其原型。

  • 每一个构造函数天生自带一个prototype属性,是一个对象数据类型
  • 每一个对象天生自带一个__proto__属性,指向所属构造函数的prototype属性。当访问对象的成员的时候,首先会在自己的身上查找,如果没有,则会到__proto__上查找。

原型链的引出:

function Person(name, age) {
    this.name = name;
    this.age = age;
}
var p1 = new Person("张三", 20);
console.log(p1.__proto__);
// 把想添加给实例对象的方法添加在原型上
Person.prototype.sayHi = function () {
    console.log("hello world");
};
p1.sayHi();

 问题1:实例对象(p1)身上的__proto__指向谁?

         答:指向所属构造函数(Person)的prototype。

问题2:Person.prototype的__proto__指向谁?(prototype也是个对象,所以有__proto__)

        答:因为Person.prototype是一个对象数据类型(object),在JS中,所有的Object数据类型都是属于Object这个内置构造函数的,所以Person.prototype是属于Object这个内置构造函数的,所以Person.prototype的__proto__指向Object.prototype。

问题3:Person这个构造函数也是个对象,它的__proto__指向谁?

        答:Person是一个函数,函数本身也是个对象,就会有一个__proto__,在JS中,所有的函数都是属于内置构造函数Function的实例,所以Person的__proto__指向Function.prototype。

问题4:Object.prototype的__proto__指向谁?

        答:Object.prototype是一个对象数据类型,只要是对象,都是属于Object这个内置构造函数的,Object.prototype的__proto__指向Object.prototype。

        上面的说法对吗?其实是不对的,这样的话就出现了死循环

        注意:Object.prototype在JS内叫做顶级模型,不再有__proto__属性,所以Object.prototype的__proto__指向null。

问题5:Object的__proto__指向谁?

        答:Object是一个内置构造函数,是一个对象,同时也是一个函数,在JS中,所有的函数都是属于内置构造函数 Function 的实例,Object也是 Function的实例,所以Object的__proto__指向Function.prototype

问题6:Function.prototype的__proto__指向谁?

        答:Function.prototype是一个对象数据类型,只要是对象,都是Object的实例,Function.prototype的__proto__指向Object.prototype。

问题7:Function的__proto__指向谁?

        答Function是一个内置构造函数,是一个函数,在JS内,所有的函数都是属于内置构造函数Function的实例,Function自己是自己的实例对象,Function所属的构造函数是Function。

从上面的七个问题,从而也就知道了对象的访问机制

  • 当你需要访问对象的成员的时候,首先会在自己身上查找,如果有就直接使用;
  • 如果没与,会自动去__proto__上查找;
  • 如果还没有,则会去对象.__proto____proto__上查找;
  • 直到Object.prototype都没有,则会返回null;

那么什么是原型链呢?

        用__proto__串联起来的对象链状结构,就是原型链,并且每一个对象数据类型都有一个属于自己的原型链。

        原型链的作用就是便于访问对象成员

三、原型链笔试题

1、如何判断自有还是共有属性?

        判断自有属性:obj.hasOwnProperty(),true就是自有,false是共有/根本没有。

        判断共有:2个条件

                1、不是自有属性。

                2、在原型链上去检查:"属性名" in 对象名,true就是共有。

if(obj.hasOwnProperty("属性名")){
    console.log("自有")
}else{
    if("属性名" in obj){
        console.log("共有")
    }else{
        console.log("没有")
    }
}

2、如何为老版本IE添加indexOf方法?

//如果数组的原型上(也就是Object上)没有indexOf方法的话
if(Array.prototype.indexOf===undefined){
    Array.prototype.indexOf=function(key,starti){
        start1==undefined&&starti==0
        for(var i=starti;i<this.length;i++){
                if(this[i]===key){
                    return i
                }
        }
        return -1
    }
}

3、如何判断一个对象是不是数组?

        可以有四个方法,但要注意:typeof并不能判断!!!

        typeof总共有六种返回值:number、boolean、string、function、object、undefined。当对数组使用typeof的时候,会发现得到的结果是Object,所以并不能使用typeof区分一个对象是不是数组。

1)、判断xxx是不是继承自Array.prototype

        Array.prototype.isPrototypeOf(xxx): true就是数组,false就不是。

2)、判断xxx是否由构造函数Array创建的

        xxx instanceof Array:true就是由Array创建,false就不是。

3)、ES5提供的一个方法

        Array.isArray(xxx):true就是数组。此方法不是人人都有,而且ES5以上的东西,老IE都不支持。

4)、输出对象的字符串形式

        在Object的prototype原型上放着最原始的toString,默认输出[object 构造函数名]

        Object.prototype.toString.apply/call(xxx)==="[object Array]":true就为数组。

var arr = [1, 2, 3, 4, 5, 6];
console.log(Array.prototype.isPrototypeOf(arr));
console.log(arr instanceof Array);
console.log(Array.isArray(arr));
console.log(Object.prototype.toString.call(arr));

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值