JavaScript ES6 類和對象 簡單記錄


/*
1.在ES6以前若是定義一個類?
經過構造函數來定義一個類
*/
        function Person(myName, myAge) {
            // 實例屬性
            // this.name = "lnj";
            // this.age = 34;
            this.name = myName;
            this.age = myAge;

            // 實例方法
            this.say = function () {
                console.log(this.name, this.age);
            }
            // 靜態屬性
            Person.num = 666;
            // 靜態方法
            Person.run = function () {
                console.log("run");
            }
        }
        // let p = new Person();
        let p = new Person("zs", 18);
        p.say();
        console.log(Person.num);
        Person.run();
/*
2.從ES6開始系統提供了一個名稱叫作class的關鍵字, 這個關鍵字就是專門用於定義類的
*/
  class Person{
            // 當咱們經過new建立對象的時候, 系統會自動調用constructor
            // constructor咱們稱之爲構造函數
            constructor(myName, myAge){
                this.name = myName;
                this.age = myAge;
            }
            // 實例屬性
            // name = "lnj";
            // age = 34;
            // 實例方法
            say(){
                console.log(this.name, this.age);
            }
            // 靜態屬性
            static num = 666;
            // 靜態方法
            static run() {
                console.log("run");
            }
        }
        // let p = new Person();
        let p = new Person("zs", 18);
        p.say();
        console.log(Person.num);
        Person.run();

須要注意的地方:瀏覽器

app

class Person{
            // 如下定義"實例屬性"的方式並非ES6正式版標準中的寫法, 大部分的瀏覽器不支持
            // 在ES6標準中添加實例屬性都須要在constructor中添加
            // 實例屬性
            // name = "lnj";
            // age = 34;
            constructor(){
                this.name = "lnj";
                this.age = 34;
            }
            // 實例方法
            say(){
                console.log(this.name, this.age);
            }
        }
        let p = new Person();
        console.log(p);

函數

 class Person{
            // 如下定義"靜態屬性"的方式並非ES6正式版標準中的寫法, 大部分的瀏覽器不支持
            // 在ES標準中static只支持定義靜態方法不支持定義靜態變量
            // 靜態屬性
            // static num = 666;

            // 靜態方法
            static run() {
                console.log("run");
            }
        }
        Person.num = 666;
        let p = new Person();
        console.log(p);

 

this

function Person(myName, myAge) {
            // 實例屬性
            this.name = myName;
            this.age = myAge;
            // 實例方法
            
            this.hi = function () {
                console.log("hi");
            }
        }
        // 原型上的方法
        Person.prototype.say = function () {
            console.log(this.name, this.age);
        }
        let p = new Person("lnj", 34);
        console.log(p);


        class Person{
            constructor(myName, myAge){
                this.name = myName;
                this.age = myAge;
              //構造函數裏面添加的方法會添加到 對象自己
                this.hi = function () {
                    console.log("hi"); }
            }
            //在類裏面添加的方法會加到原型對象中
            say(){
                console.log("hi"); }
        }
        let p = new Person("lnj", 34);
        console.log(p);

spa

注意點:
若是經過class定義類, 那麼不能自定義這個類的原型對象
若是想將屬性和方法保存到原型中, 只能動態給原型對象添加屬性和方法
 function Person(myName, myAge) {
            // 實例屬性
            this.name = myName;
            this.age = myAge;
            // 實例方法
            this.hi = function () {
                console.log("hi");
            }
        }
        // 原型上的方法
        // Person.prototype.type = "人";
        // Person.prototype.say = function () {
        //     console.log(this.name, this.age);
        // };
        //function方式定義的構造函數能夠修改 原型對象
        Person.prototype = {
            constructor: Person,
            type: "",
            say: function () {
                console.log(this.name, this.age);
            }
        };


        class Person{
            constructor(myName, myAge){
                this.name = myName;
                this.age = myAge;
                this.hi = function () {
                    console.log("hi");
                }
            }
            run(){
                console.log("run");
            }
        }
        // Person.prototype.type = "人";
        // Person.prototype.say = function () {
        //     console.log(this.name, this.age);
        // };

        let obj = {
            constructor: Person,
            type: "",
            say: function () {
                console.log(this.name, this.age);
            }
        };
        //修改對象原型無效
        Person.prototype = obj;

        let p = new Person("lnj", 34);
        console.log(p);

五  繼承prototype

 ES6以前的繼承
1.在子類中經過call/apply方法藉助父類的構造函數
2.將子類的原型對象設置爲父類的實例對象
function Person(myName, myAge) {
            this.name = myName;
            this.age = myAge;
        }
        Person.prototype.say =  function () {
            console.log(this.name, this.age);
        }
        function Student(myName, myAge, myScore) {
            // 1.在子類中經過call/apply方法藉助父類的構造函數
            Person.call(this, myName, myAge);
            this.score = myScore;
            this.study = function () {
                console.log("day day up");
            }
        }
        // 2.將子類的原型對象設置爲父類的實例對象
        Student.prototype = new Person();
        Student.prototype.constructor = Student;

        let stu = new Student("zs", 18, 99);
        stu.say();
1.在ES6中如何繼承
1.1在子類後面添加extends並指定父類的名稱
1.2在子類的constructor構造函數中經過super方法藉助父類的構造函數
class Person{
            constructor(myName, myAge){
                // this = stu;
                this.name = myName; // stu.name = myName;
                this.age = myAge; // stu.age = myAge;
            }
            say(){
                console.log(this.name, this.age);
            }
        }
        /*
        1.在ES6中如何繼承
        1.1在子類後面添加extends並指定父類的名稱
        1.2在子類的constructor構造函數中經過super方法藉助父類的構造函數
        */
        // 如下代碼的含義: 告訴瀏覽器未來Student這個類須要繼承於Person這個類
        class Student extends Person{
            constructor(myName, myAge, myScore){
                // 1.在子類中經過call/apply方法藉助父類的構造函數
                // Person.call(this, myName, myAge);
                super(myName, myAge);
                this.score = myScore;
            }
            study(){
                console.log("day day up");
            }
        }
        let stu = new Student("zs", 18, 98);
        stu.say();

六  獲取對象類型code

 let obj = new Object();
        console.log(typeof obj); // object

        let arr = new Array();
         /*
         * 這樣的打印會是object,這是由於 在全部構造函數中,內部其實會新建一個Object對象,而後賦值給this
         * */
         console.log(typeof arr); // object
        console.log(arr.constructor.name); // Array


        function Person() {
            // let obj = new Object();
            // let this = obj;
            this.name = "lnj";
            this.age = 34;
            this.say = function () {
                console.log(this.name, this.age);
            }
            // return this;
        }
        let p = new Person();
        // console.log(typeof p); // object
        console.log(p.constructor.name); // Person

七 instanceof 關鍵字對象

1.什麼是instanceof關鍵字?
instanceof用於判斷 "對象" 是不是指定構造函數的 "實例"

   2.instanceof注意點blog

只要 構造函數的原型對象出如今實例對象的原型鏈中都會返回true
 class Person{
            name = "lnj";
        }
        let p = new Person();
        console.log(p instanceof Person); // true

        class Cat{
            name = "mm";
        }
        let c = new Cat();
        console.log(c instanceof Person); // false


        function Person(myName) {
            this.name = myName;
        }
        function Student(myName, myScore) {
            Person.call(this, myName);
            this.score = myScore;
        }
        Student.prototype = new Person();
        Student.prototype.constructor = Student;

        let stu = new Student();
        /*
        * 返回true的緣由爲 Person的原型對象出如今了stu的原型鏈上
        * */
        console.log(stu instanceof Person); // true

 

八 isPrototypeOf繼承

1.什麼是isPrototypeOf屬性
isPrototypeOf用於判斷 一個對象是不是另外一個對象的原型
2.isPrototypeOf注意點
2.1只要調用者在傳入對象的原型鏈上都會返回true

 class Person{
            name = "lnj";
        }
        let  p = new Person();
        console.log(Person.prototype.isPrototypeOf(p)); // true

        class Cat{
            name = "mm";
        }
        console.log(Cat.prototype.isPrototypeOf(p)); // false
        

        function Person(myName) {
            this.name = myName;
        }
        function Student(myName, myScore) {
            Person.call(this, myName);
            this.score = myScore;
        }
        Student.prototype = new Person();
        Student.prototype.constructor = Student;

        let stu = new Student();
        console.log(Person.prototype.isPrototypeOf(stu)); // true

八 判斷某一個對象是否擁有某一個屬性

// 需求: 判斷某一個對象是否擁有某一個屬性
        class Person{
            name = null;
            age = 0;
        }
        Person.prototype.height = 0;
        
        let p = new Person();
        // in的特色: 只要類中或者原型對象中有, 就會返回true
        console.log("name" in p); // true
        console.log("width" in p); // false
        console.log("height" in p); // true
        

        // 需求: 判斷某一個對象自身是否擁有某一個屬性
        let p = new Person();
        // 特色: 只會去類中查找有沒有, 不會去原型對象中查找
        console.log(p.hasOwnProperty("name")); // true
        console.log(p.hasOwnProperty("height")); // false

九 深拷貝和淺拷貝

1.什麼是深拷貝什麼是淺拷貝?
1.1深拷貝
修改新變量的值不會影響原有變量的值
默認狀況下基本數據類型都是深拷貝

1.1淺拷貝
修改新變量的值會影響原有的變量的值
默認狀況下引用類型都是淺拷貝

萬能深拷貝方法
class Person{
            name = "lnj";
            cat = {
                age : 3
            };
            scores = [1, 3, 5];
        }
        let p1 = new Person();
        let p2 = new Object();
        /*

        // p2.name = p1.name;
        // p2.name = "zs";
        // console.log(p1.name);
        // console.log(p2.name);
        p2.cat = p1.cat;
        p2.cat.age = 666;
        console.log(p1.cat.age);
        console.log(p2.cat.age);
        */

        depCopy(p2, p1);
        // console.log(p2);

        p2.cat.age = 666;
        console.log(p1.cat.age);
        console.log(p2.cat.age);

        function depCopy(target, source) {
            // 1.經過遍歷拿到source中全部的屬性
            for(let key in source){
                // console.log(key);
                // 2.取出當前遍歷到的屬性對應的取值
                let sourceValue = source[key];
                // console.log(sourceValue);
                // 3.判斷當前的取值是不是引用數據類型
                if(sourceValue instanceof Object){
                    // console.log(sourceValue.constructor);
                    // console.log(new sourceValue.constructor);
                    let subTarget = new sourceValue.constructor;
                    target[key] = subTarget;
                    depCopy(subTarget, sourceValue);
                }else{
                    target[key] = sourceValue;
                }
            }
        }
相關文章
相關標籤/搜索