23-JS高级:原型链、constructor构造函数、继承

1.原型链

每一个实例对象有__proto__属性,指向的是构造函数的原型对象,构造函数的原型对象也是一个对象,也有__proto__属性,这样一层一层往上找就形成了原型链

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    

    <script>
    

    // 在构造函数中,定义属性和方法  只要实例化一个对象,就会重新创建方法sing 就会开辟内存空间
    // 浪费内存

    // 我们要多个对象共用一个方法  把方法定义到原型对象中




    function Star(name,age){
        this.name = name;
        this.age = age;
    }

    // 原型对象
    Star.prototype.sing = function(){
        console.log('唱歌把');
    }

    // 1.实例化对象  只要是对象就有__proto__   指向原型对象
    var s1 = new Star('张三',12);
    s1.sing()

    console.log(Star.prototype);
    // new Object
    // 2.我们Star原型对象的__proto__指向的是Object.prototype
    console.log(Star.prototype.__proto__ === Object.prototype)  //true
    // 3.我们Object.prototype原型对象的__proto__指向null
    console.log(Object.prototype.__proto__);  //null
    </script>
</body>
</html>

2.constructor构造函数

对象原型 proto 和构造函数prototype 原型对象里都有一个属性 constructor
constructor 我们称为构造函数,因为他指回构造函数本身
constructor 主要用来记录对象引用于那个构造函数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    

    <script>
    



    function Star(name,age){
        this.name = name;
        this.age = age;
    }


    // 我们修改了原来的原型对象 给原型对象赋值的是一个对象
    // 我们手动的给constructor 指回原来的构造函数
    Star.prototype = {
        constructor:Star,  //手动设置指向原来的构造函数
        sing:function(){
            console.log('唱歌')
        },
        movie:function(){
            console.log('看电影')
        }
    }

    var s = new Star('李四',23);
    console.log(s);
    </script>
</body>
</html>

3.原型对象中this的指向

构造函数中的this和原型对象中的this 都指向我们new出来的实例对象

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
    <script>

    function Star(name,age){
        this.name = name;
        this.age = age;
    }

    Star.prototype.sing = function(){
        console.log('唱歌把')
    }

    Star.prototype.sex = '女';

    var s = new Star('小写',34);
    console.log(s.sex);  //女
    console.log(Object.prototype);
    console.log(s);
    console.log(Star.prototype);
    console.log(s.toString());



    /* 
    当访问一个对象的属性或方法时,首先先查找这个对象自身有没有该属性
    如果没有就找它的原型(也就是__prot__指向的prototype原型对象)
    如果还没有找到就查找原型对象的原型(Object的原型对象)
    类推 一直找到Object为止  null
    */


    </script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
    <script>

        /* 
        构造函数中的this和原型对象中的this都指向我们new出来的实例对象
        */

        function Star(name,age){
        this.name = name;
        this.age = age;
    }

    var that;
    Star.prototype.sing = function(){
        console.log('我会唱歌');
        that = this;
    }

    var s = new Star('小妞' ,23);
    s.sing();
    console.log(that === s);   //true
    </script>
</body>
</html>

4.继承

call

call() 可以调用函数

call()可以修改this的指向,使用call()的时候,参数1是修改后的this指向,参数2,参数3 使用逗号隔开

构造函数继承

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
    <script>

    //  function fn(x,y){
    //      console.log('我想吃');
    //      console.log(this);
    //      console.log(x + y);
    //  }

    //  var o = {
    //      name:'zx'
    //  }

    //  fn(12,34);

    /* 
    call()可以调用函数

    call()可以修改this指向,使用call()的时候,参数1是修改后的this指向,参数2,参数3 使用逗号隔开
    
    */

    // fn.call(o,23,56);


    //  构造函数继承
    // 只能继承父类的实例属性和方法  不能继承原型属性或者方法


    // 父构造函数
    function Parentl(){
        this.name = 'parentl'
    }


    Parentl.prototype.getName = function(){
        return this.name
    }


    // 子构造函数
    function Child(){
        // this指向子构造函数的对象实例
        Parentl.call(this);  //c
        this.type = 'child';
    }

    var c = new Child();
    console.log(c);
    console.log(c.getName())  //报错

    // 父类原型对象中一旦存在父类之前自己定义的方法,那么子类将无法继承这些方法
    </script>
</body>
</html>

借用原型对象继承方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
    <script>

    //  1.父构造函数
    function Parentl(name,age){
        // this指向父构造函数的实例
        this.name = name;
        this.age = age;
    }


    Parentl.prototype.money = function(){
        console.log(1000000);
    }


    // 子构造函数
    function Child(name,age,score){
        // this指向子构造函数的对象实例
        Parentl.call(this,name,age);  //c
        this.score = score;
    }

    Child.prototype = new Parentl();
    // 利用对象的形式修改了原型对象,手动设置constructor
    Child.prototype.constructor = Child

    Child.prototype.ks = function(){
        console.log('考试')
    }

    var c = new Child('zs',20,98);
    console.log(c);
    console.log(c.money)
    console.log()

    </script>
</body>
</html>

5.数组新增方法

通过原型为数组扩展内置方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    

    <script>

        /* 
        数组.push
        数组.splice
        数组.shift
        ---------
        都是定义在
        Array.prototype原型对象上
        */

        // var arr = new Array()
        // console.log(arr)



        // 为数组扩展内置的方法
        Array.prototype.sum = function(){
            // this 指向的是arr
            var sum = 0;
            for(var i =0; i < this.length; i++){
                sum += this[i]
            }
            return sum
        }

        var arr = new Array()
        arr.push(23,45,1,2,4,5,7)
        console.log(arr)
        console.log(arr.sum());


    </script>
</body>
</html>

forEach遍历数组

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    

    <script>
        var arr = [12,4,5,6,78,5,4,32,46,8,9];

        // arr.forEach(function(value,index,array){
        //     // value数组每一个元素
        //     // index数组元素的索引
        //     // array 当前的数组
        //     console.log(value,index,array);
        // })

        // // forEach 数组遍历  相当于for循环
        // arr.forEach((item,index,arr)=>{
        //     console.log(item,index,arr)
        // })



        // ----------------------------
        // filter过滤数组  返回过滤后的新数组

       var newarr = arr.filter(function(value,index,array){
            return value >=10
        })
        console.log(newarr)  //[12, 78, 32, 46]

        // some  every  findIndex  map
    </script>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
原型链继承(Prototype Inheritance)在JavaScript中是通过创建一个新对象并让它引用另一个对象的原型来实现的。例如: ```javascript function Parent() {} Parent.prototype.method = function() { console.log('Parent method'); }; let child = new Parent(); child.method(); // 输出: "Parent method" ``` **借用构造函数继承**(Constructo r Chaining)利用已有构造函数作为父类,通过`new`关键字传递给子类实例化过程,间接实现了继承: ```javascript function Parent() { this.parentProp = 'parent'; } function Child() { Parent.call(this); // 借用父类构造函数 this.childProp = 'child'; } Child.prototype = Object.create(Parent.prototype); Child.prototype.constructor = Child; let childInstance = new Child(); console.log(childInstance.parentProp); // 输出: "parent" console.log(childInstance.childProp); // 输出: "child" ``` **组合式继承**(Mix-in or Prototype Mixing)结合原型链构造函数继承,允许从多个源继承属性和方法: ```javascript function Mixin(target) { for (let prop in Mixin.prototype) { target[prop] = Mixin.prototype[prop]; } } function Parent() { this.parentProp = 'parent'; } Mixin(Parent.prototype); let child = new Parent(); console.log(child.parentProp); // 输出: "parent" ``` **ES6的class类继承**(Class-based Inheritance)使用`extends`关键字实现: ```javascript class Parent { constructor() { this.parentProp = 'parent'; } parentMethod() { console.log('Parent method'); } } class Child extends Parent { constructor() { super(); this.childProp = 'child'; } childMethod() { console.log('Child method'); } } let childInstance = new Child(); childInstance.parentMethod(); // 输出: "Parent method" childInstance.childMethod(); // 输出: "Child method" ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值