1. 程式人生 > 其它 >C++的四種cast——dynamic_cast

C++的四種cast——dynamic_cast

建構函式和原型

一.建構函式和原型

1、建構函式

1.概述

建構函式是一種特殊的函式,主要用來初始化物件,即為物件成員變數賦初始值,它總與new一起使用,我們可以吧物件中一些公共的屬性和方法抽取出來,然後封裝到這個函式裡面。

new在執行時會做四件事

  1. 在記憶體中建立一個新的空物件;

  2. 讓this指向這個新的物件;

  3. 執行建構函式裡面的程式碼,給這個新物件新增屬性和方法;

  4. 返回這個新物件(所以建構函式裡面不需要return)。

建立物件的三種方式:

1.物件字面量

var obj1={};
  1. new Object()

var obj2=new Object();

3.自定義建構函式

function Star(uname,age){
    this.uname=name;
    this.age=age;
    this.sing=function(){
        console.log("我會唱歌啊");
    }
}
var ldh=new Star('劉德華',42);
var zxy=new Star('張學友',46);
ldh.sing();
zxy.sing();
​

下文皆使用這個例子來說明。

2.成員

JavaScript的建構函式中可以新增一些成員,可以在建構函式本身新增,也可以在建構函式內部的this上新增。通過這兩種方式新增的成員,就分別為靜態成員

例項成員

  • 靜態成員:在建構函式本身上新增的成員,只能由建構函式本身來訪問;

function Star(uname,age){
    this.uname=name;
    this.age=age;
    this.sing=function(){
        console.log("我會唱歌啊");
    }
}
Star.sex="男";//在建構函式本身新增  就是靜態成員
console.log(Ster.sex);//只能通過本身來訪問
  • 例項成員:在建構函式內部建立的物件成員,只能由例項化的物件來訪問。

function Star(uname,age){
    this.uname=name;
    this.age=age;
    this.sing=function(){
        console.log("我會唱歌啊");
    }
}
var ldh=new Star('劉德華',42);
//這裡面的 uname  age sing  就是例項成員,都是通過this新增的成員。只能通過例項物件ldh來訪問

2.物件原型prototype

建構函式雖然很好用,但是存在浪費記憶體的問題~

美創造一個都會開闢一個新的空間。

這就來了原型prototype 解決這個問題~

建構函式通過原型分配的函式是所有物件共享的;

JavaScript規定:每一個建構函式都有一個prototype屬性,指向另一個物件。注意這個prototype就是一個物件,這個物件的所有屬性方法,都會被建構函式擁有。

我們把那些不變的方法直接定義在原型物件上,這樣所有的物件的例項就可以共享這些方法,就節約了記憶體空間。

function Star(uname,age){
    this.uname=name;
    this.age=age;
}
​
Star.prototype.sing=function(){
        console.log("我會唱歌啊");
    }//把sing這個方法定義在原型上
​
var ldh=new Star('劉德華',42);
var zxy=new Star('張學友',46);
ldh.sing();
zxy.sing();
​

3.原型物件 proto

物件都會有一個屬性proto指向建構函式的prototype原型物件,之所以我們物件可以使用建構函式prototype原型物件的屬性和方法,就是因為物件proto的存在。

  • proto物件原型和原型物件prototype是等價的

console.log(ldh.__proto__ === Star.prototype)//true
  • proto物件原型的意義就在於為物件的查詢機制提供一個路線。但是是一個非標準屬性,在實際開發中,不可以使用這個屬性,他只是內部指向原型物件prototype。

來張圖理解理解~

4. constructor建構函式

物件原型(proto)和原型物件(prototype)都有一個constructor屬性,constructor我們稱為建構函式,因為它指回建構函式本身。

很多情況下,我們需要用constructor函式指回原來的建構函式。

Star.prototype={
    constructor:Star,//如果不新增這一步,那麼就會把原來的物件覆蓋,因此不會指向原來的建構函式
    Sing:fnction(){
    console.log("我會唱歌");
},
     Movie:fnction(){
    console.log("我會演電影");
}
}
​
console.log(Star.prototype.constructor);
//指回原來的建構函式

5.三者的關係

 

6.原型鏈

查詢成員是按照這個原型鏈一層一層找下去,如果沒找到,就返回undifined。

成員查詢規則

  1. 當訪問一個物件的屬性時,首先查詢這個物件自身有沒有這個屬性;

  2. 如果沒有就查詢他的原型也就是proto指向的prototype原型物件;

  3. 如果也沒有找到,就查詢原型物件的原型(Object的原型物件);

  4. 依此類推直到找到Object為止(null)。

7.擴充套件內建物件

通過原型物件,對原來的內建物件進行擴充套件自定義的方法。

例子:新增一個加法方法sum

<script>
        Array.prototype.sum = function () {
            var sum = 0;
            for (var i = 0; i < this.length; i++) {
                sum += this[i];
            }
            return sum;
        }
        var arr = [1, 2, 3];
        console.log(arr.sum());
</script>

注意:陣列和字串內建物件不能給原型物件覆蓋操作Array.prototype={},只能是Array.prototype.xxx=function(){}的方式。

二、繼承

ES6之前不提供extends繼承,可以通過建構函式+原型物件模擬實現繼承,被稱為組合繼承。

1.call( )

呼叫這個函式,並且修改函式執行時的this指向。

fun.call(當前呼叫函式this的指向物件,引數1,引數2,...)

function myFunction(a, b) {
    return a * b;
}
myObject = myFunction.call(myObject, 10, 2);     // 返回 20

2.借用父建構函式繼承屬性

例子:

 <script>
        function Father(uname, age) {
            this.uname = name;
            this.age = age;
        }
​
        function Son(uname, age) {
            Father.call(this, uname, age);
        }
        var son = new Son('劉德華', 34);
        console.log(son);//添加了這兩個屬性
    </script>

2.借用原型物件繼承屬性

<script>
        function Father(uname, age) {
            this.uname = name;
            this.age = age;
        }
        Father.prototype.money = function () {
            console.log('賺了10000塊');
        }
        Son.prototype = new Father();
        //用了物件的形式秀髮i了原型物件用constructor指回原來的建構函式
        Son.prototype.constructor = Son;
​
        function Son(uname, age, score) {
            Father.call(this, uname, age);
            this.score = score;
        }
        var son = new Son('劉德華', 34, 100);
        console.log(son);
        console.log(Son.prototype.constructor);
    </script>
​

圖片分析過程:

在Father原型物件上添加了money這個方法,當Son要使用這個方法時,建立一個Father例項物件,Son原型物件指向這個例項物件,這個例項物件裡面有一個proto物件原型指向Father原型物件,也就相當於繼承到了這個方法。

 

 

本文為pink老師視訊的筆記,原視訊指路:

https://www.bilibili.com/video/BV1f5411t7dq?p=13&spm_id_from=pageDriver