JS高級--面向對象

一、對象定義的三種方式

一、對象的構成、

對象是由它本身和它的原型公共構成的, 對象的原型是 proto (也是一個對象)

二、原型鏈:

對象或構造函數(shù)由本身和原型構成,對象或構造函數(shù)也是一個對象,由本身和原型構成,這樣一直往后沿深,形成原型鏈。

二、定義對象鍵和鍵值

分為直接定義、追加定義

var obj2 = new Object();
// 添加對像內容
obj2.name = "張三";
obj2.age = 20;
console.log(obj2);
// 覆蓋定義 obj2對象
obj2 = {
    height:"178cm",
    hobby:function(){
        console.log("喜歡籃球");
    }
}
console.log(obj2);

三、對象和JSON之間的轉換

JSON鍵名一定要加 "",鍵值沒有函數(shù),規(guī)范 :引號使用--外單內雙
 var JSON = '{"name":"張三","age":"19"}';

var json1 = JSON.stringify(obj2);   // 對象轉json串(字符串化)
var newObj = JSON.parse(json1);     // json數(shù)據(jù)轉換成對象(解析)


四、傳值和傳址問題

1、傳值,

var a = 10;
var b = a;
b = 5;
console.log(a,b); // 10 5 。不會相互影響

2、傳址

var obj1 = {
    a:10
}
var obj2 = obj1;
obj2.a = 5;
console.log(obj1.a,obj2.a);  // 5 5

// 數(shù)組傳址,數(shù)組之間相互影響
var arr1 = [1,2,3,4,5];
var arr2 = arr1;
arr2[1] = 10;
console.log(arr1[1]);        // 10

解決傳址問題:

1、深拷貝 -- 將數(shù)組轉為JSON串,再轉為數(shù)組

var arr1 = [1,2,3,4,5];
var arr2 = JSON.parse(JSON.stringify(arr1));
arr2[1] = 10;
console.log(arr1);         // 2

2、使用空的構造函數(shù),作為兩個函數(shù)原型的橋梁。

解決方案: 空的構造函數(shù),作為父級、子級的傳遞橋梁。

function People(sex,eat){
    this.sex = sex;
    this.eat = eat;
}
People.prototype.actions = () => {
    console.log('People === actionsFn')
}

function Student(sex,eat){
    this.sex = sex;
    this.eat = eat;
}
Student.prototype.actions = () => {
    console.log('Student === actions')
}

------------------------------
 Student.prototype = People.prototype;
------------------------------


++++++++++++++++++++++++++++++
function Link(){
    Link.prototype = People.prototype;
    
}
Student.prototype = new Link;
+++++++++++++++++++++++++++++++


Student.prototype.actions = () => {
    console.log('Stundent === New');
}

const newPeo = new People('女','水果');
const newStu = new Student('man','dontknow');
newPeo.actions();
newStu.actions();


五、構造函數(shù)

構造函數(shù)(類似類的概念); 約定俗成:首字母大寫

1、定義構造函數(shù)
function People(eat,age){
    this.eat = eat;
    this.age = age;
    this.action = function(){
        console.log("吃飯,睡覺");
    }
}
2、構造函數(shù)的原型
  • 構造函數(shù)由本身和原型prototype構成;
  • 原型鏈:原型是一個構造函數(shù),又由本身和構造函數(shù)構成,一直往后延深,形成原型鏈。
  • 一般屬性寫在構造函數(shù)里,方法寫在原型上,目的是:便于維護
  • 在寫方法時,直接:People.prototype = function({}),會覆蓋原有的原型
    People.prototype.action = function(){
        console.log(this);  // 實列化是誰,this指向誰。
        console.log(this.eat);
        console.log("我是爸爸");
    }
3、通過原型找構造函數(shù)
console.log(People.prototype.constructor);
4、調用構造函數(shù)

關鍵字 new:實列化構造函數(shù)。抽象具體化,將類變?yōu)閷ο?/p>

newPeople = new People("米飯",18);
console.log(newPeople.eat);
newPeople.action();
5、關鍵字new具體做的三件事:

創(chuàng)建空的對象

 var newPeople = new Object();

將構造函數(shù)的this指向改變成空對象 (3種寫法:call/apply/bind)

People.call(newPeople,"米飯",18);  
//  People.apply(obj,["米飯",18])  
//  People.bind(obj)("米飯",18);

將構造函數(shù)的原型賦給對象原型

 newPeople.__proto__ = People.prototype;  // 構造函數(shù)的原型 賦給 實列化原型
6、構造函數(shù)的原型
console.log(People.prototype === newPeople.__proto__);  // true , 只是表現(xiàn)形式不一樣
7、構造函數(shù)的 -- 繼承

1、改變this指向

function Father(eat,age){
    this.eat = eat;
    this.age = age;
    this.fath = function(){
        console.log("我是爸爸");
    }
}
function Sons(eat,age){
    Father.call(this,eat,age);
    this.sonFn = function(){
        console.log("我是兒子");
    }
}

2、原型的繼承

// 不可以直接:Sons.prototype = father.prototype;
// -- 解決傳址問題 !!!
    // 1、定義一個空構造函數(shù),其原型指向father原型,son原型指向其原型

function Center(){};
Center.prototype = Father.prototype;
Sons.prototype = new Center();  // 空構造函數(shù)只有原型

Father.prototype.typeFn = function(){
    console.log("父級重寫");
}
Sons.prototype.typeFn = function(){
    console.log("子級重寫");
}
var newSons = new Sons("蘋果",10);
var newFather = new Father("蘋果",10);
console.log(newSons.eat);
newSons.sonFn();
newSons.fath();

newFather.typeFn();
newSons.typeFn();

六、類的特性:封裝、繼承、多態(tài)、重載; [js:封裝、繼承]

1、封裝 -- 公有、私有屬性
function Person3(name){
    // 1.1、私有屬性
    var name = name;
    // 1.2、公有屬性
    this.height = "179cm";
    // 1.3、get方法:通過公有方法,訪問私有屬性
    this.get = function(){
        return name;
    }
    // 1.4 set方法:設置私有屬性
    this.set = function(newname){
        name = newname;
        console.log(name);
    }
}
newPerson3 = new Person3("三三");
console.log(newPerson3.name);  // undefind:作用域問題,訪問不到。只能在構造函數(shù)內部訪問
console.log(newPerson3.get());  // 三三
 newPerson3.set("四四");         // 四四
2、繼承

1、利用 apply、call、bind 方法,改變this指向 實現(xiàn)繼承

  • 通過 apply、call、bind:繼承父類 的 this ----> 只能繼承實例的 方法、對象
  • 父類公有對象、方法 都通過 this 遞增,每 new 一個 實例都導致 this 內容的存儲,耗費很大內存
function Student(name, age, grade){

    // 將 this 指向 Person,達到繼承 Person對象實例 的 方法、目的
    Person.apply(this, arguments);  
    // Person.call(this, arguments);
    // Person.bind(this)(arguments);
    this.grade = grade;
}

function Person(name, age){
    this.age = age;
    this.name = name;
    this.type = 'person';
}
Person.prototype.proFn = () => {
    console.log('Person === proFn')
}

var student = new Student('sname', 'sage', 'sgrade');
console.log(student);



2、空對象作為中介

  • 只能通過 Prototype 來傳遞
  • 優(yōu)勢:
    少 new 很多的 this 構造函數(shù),節(jié)省內存
    子類 prototype 改變,不影響父類
function Student(name , age, grade){
    this.grade = grade;
}
function Person(name, age){
    this.name = name;
    this.age = age;
}
Person.prototype.type = 'preson';

function Extend(Child, Partent){
    var F = function(){};                // 空對象
    F.prototype = Partent.prototype;    
    Child.prototype = new F();
    Child.prototype.constructor = Child; // 將 Child 賦給 當前對象的構造函數(shù) ( 防止繼承鏈的紊亂,需手動把構造器指回Child )
    Child.uber = Partent.prototype;      // Child 的 Uber 屬性,直接指向 Partent 的 prototype (只是為了實現(xiàn)繼承的完備性,純屬備用性質)
}

Extend(Student, Person);
var student = new Student('sname', 'sage', 'sgrade');
Student.prototype.subType = 'ssubType';
console.log('student +++', student.type)
console.log('student +++', student.subType)

3、拷貝繼承

    function Student(name, age, grade){
        this.grade = grade;
    }
    function Person(name, age){
        this.name = name;
        this.age = age;
    }
    function Extend(Child, Partent){
        var p = Partent.prototype;
        var c = Child.prototype;
        for (const i in p) {          // 遍歷拷貝賦值
            c[i] = p[i];
        }
        c.uber = p;
    }
    Person.prototype.type = 'person';
    Extend(Student, Person);

    Student.prototype.subType = 'sperson';
    var student = new Student('sname', 'sage', 'sgrade');
    console.log(student)

七、工廠模式

function Factory(height){
    //obj人類
    var obj = {};
    obj.name = 20;
    obj.name = "張三";
    obj.height = height;
    obj.hobby = function(){
        console.log("我喜歡籃球");
    }
    return obj;
}
var newFactory = Factory("162");
console.log(newFactory.height);
newFactory.hobby();
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容