第9天:原型、繼承、函數使用推薦以及this的指向

原型

javascript原型指向改變如何添加方法和訪問

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script>
        //構造函數
     function Person(age){
         this.age = age;
     }
     //構造函數
     function Student(){
         this.sayHi = function(){
             alert("1");
             console.log("學生");
         }
         this.name = "名字";
     }
     //實例對象改變原型指向
     Student.prototype = new Person(10);
     //實例化
     var stu = new Student();
     //沒有返回的值  爲undefined
     //在調用sayHi()的時候,執行了sayHi()的函數代碼
      console.log(stu.sayHi());
      //要想改變原型後而且調用添加的方法,要在改變指向以後再添加
      Student.prototype.sayHell = function(){
         console.log("說hello");
     }
      stu.sayHell();
    </script>
</head>
<body>
</body>
</html>

繼承

面向對象的特性:封裝、繼承、多態、(若是是變成語言還有抽象性);
|繼承,類與類之間的關係,面向對象的語言的繼承是爲了多態服務的
js不是面向對象的語言,可是能夠模擬面向對象,模擬繼承,爲了節省內存空間
繼承:
原型的做用:數據共享、繼承;目的是:爲了節省內存空間;
有幾種方式實現:javascript

  1. 原型繼承:改變原型的指向;
  2. 借用構造函數繼承:主要解決屬性的問題(原型繼承時,初始化對象數據固定(s屬性))
  3. 組合繼承:原型繼承+借用構造函數
    既然解決屬性的問題,又能解決方法問題
  4. 拷貝繼承:就是把對象中須要共享給的屬性或者方法,直接遍歷的方式複製到另一個對象中html

    繼承

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script>
    //聲明構造函數
    function Person(name,age,sex){
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
    //經過原型添加方法
    Person.prototype.play=function(){
        console.log("人能夠玩");
    }
    Person.prototype.eat = function(){
        console.log("人能夠吃東西");
    }
    Person.prototype.sleep = function(){
        console.log("人能夠睡覺");
    }
    //聲明構造函數
    function Student(scote){
        this.scote = scote;
    }
    //經過原型改變指向,並實例化對象
    Student.prototype = new Person("小紅",18,"女");
    Student.prototype.study = function(){
        console.log("須要學習啊");
    }
    //實例化對象
    var stu = new Student(100);
    console.log("繼承共同屬性");
    console.log(stu.name);
    console.log(stu.age);
    console.log(stu.sex);
    stu.play();
    stu.eat();
    stu.sleep();
    console.log("屬性student的屬性")
    stu.study();
   
    </script>
</head>
<body>
    
</body>
</html>

繼承的案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script>
    //聲明動物的構造函數
    function Animal(name,weight){
        this.name = name;
        this.weight = weight;
    }
    //動物的原型的方法
    Animal.prototype.eat = function(){
        console.log("會吃東西");
    }
    //聲明Dog的構造函數
    function Dog(furColor){
        this.furColor = furColor;
    }
    //改變原型指向,實例化對象,實現繼承
    Dog.prototype= new Animal("哮天犬","20kg");
    Dog.prototype.bite = function(){
        console.log("會咬人");
    }
    //聲明二哈的構造函數
    function Erha(sex){
        this.sex = sex;
    }
    //g改變原型指向,實例化對象,實現繼承
    Erha.prototype = new Dog("黑白色");
    Erha.prototype.takeDown = function(){
        console.log("哼哼~~~~~~~~~~哈哈,,,拆家");
    }
    //實例化對象
    var erHa = new Erha("雄性");
    console.log(erHa.name,erHa.weight,erHa.furColor,erHa.sex);
    erHa.eat();
    erHa.bite();
    erHa.takeDown();
    </script>
</head>
<body>
    
</body>
</html>

借用構造函數

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script>
    //構造函數Person
    function Person(name,age,sex){
        this.name = name;
        this.age= age;
        this.sex = sex;
    }
    //經過原型添加方法
    Person.prototype.say=function(){
        console.log("你好");
    }
    //構造函數Student
    function Student(name,age,sex,score){
        //借用構造函數
        Person.call(this,name,age,sex);
        this.score=score;
    }
    var stu = new Student("小明","18","男",100);
    console.log(stu.name,stu.age,stu.sex,stu.score);
    </script>
</head>
<body>
    
</body>
</html>

組合繼承

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script>
    /*
    原型實現繼承
    借用構造函數實現繼承
    組合繼承:原型繼承+借用構造函數竭誠
    
    */
    //Person構造函數
    function Person(name,age,sex){
        this.name = name;
        this.age = age;
        this.sex= sex;
    }
    //原型添加方法
    Person.prototype.sayHi=function(){
        console.log("你好");
    }
    //Student構造函數
    function Student(name,age,sex,score){
        //借用構造函數
        //能夠繼承屬性,可是不能繼承方法
        Person.call(this,name,age,sex)
        this.score = score;
    }
    //經過原型對象改變指向,實現方法的繼承
    Student.prototype = new Person();
    //驗證
    var stu1 = new Student("小明","18","男",100);
    var stu2 = new Student("大明","88","女",90);
    console.log(stu1.name,stu1.age,stu1.sex,stu1.score);
    console.log(stu2.name,stu2.age,stu2.sex,stu2.score);
    
    </script>
</head>
<body>
    
</body>
</html>

拷貝繼承

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

    }
    Person.prototype.name = "小明";
    Person.prototype.age = 18;
    Person.prototype.sayHi = function(){
        console.log("你好");
    }
    //聲明空對象
    var obj = {};
    //用for..in循環複製Person的prototype
    for(var key in Person.prototype){
        obj[key]=Person.prototype[key];
    }
    console.dir(obj);
    </script>
</head>
<body>
    
</body>
</html>

函數聲明和函數表達式的區別

  1. 若是之後寫函數,最好使用函數表達式,避免出錯
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script>
    
    //函數的聲明若是放在if-else的語句中,
    //在IE8的瀏覽器中會出現問題(建議使用函數表達式)
    if(true){
        function f1(){
            console.log("執行true的");
        }
    }else{
        function f1(){
            console.log("執行else的");
        }
    }
    f1();
    //測試IE 兼容方式
    //最好的方式
    //若是之後寫函數,最好使用函數表達式,避免出錯
    if(true){
        ff= function f1(){
            console.log("執行true的");
        };
    }
    else{
        ff= function f1(){
            console.log("執行else的");
        };
    }
    ff();
    </script>
</head>
<body>
    
</body>
</html>

關於this指向

普通函數中的this是誰----window
對象.方法中的this是誰————當前的實例對象
定時器方法中的this是誰————window
構造函數中的this是————實例對象
原型對象方法中的this是——實例對象
全部的函數實際上都是Function的構造函數建立出來的對象
var num = new Function("num1","num","return num1+ num2");java

"use strict";//嚴格模式
    function f1(){
        console.log(this);//window
    }
    window.f1();
相關文章
相關標籤/搜索