javascript基礎篇:關於js面向對象的理解

關於js中面向對象的理解

面向對象編程(oop)
它是一種編程思想 (object-oriented programming ), 咱們的編程或者學習實際上是按照 類、實例來完成的

學習類的繼承、封裝、多態javascript

封裝java

把實現一個功能的代碼封裝到一個函數中(一個類中),之後再想實現這個功能,只須要執行這個函數方法便可,不須要再重複的編寫代碼。

低耦合,高內聚
減小頁面中的冗餘代碼,提升代碼的重複使用率web

多態編程

一個類(函數)的多種形態: 重載、重寫

【重載】
後臺java,c#等編程語言中,對於重載的概念:方法名相同參數不一樣,叫作方法的重載c#

public void sum(int num1,int num2){
    //=> CODE
}
public void sum(int num1){
    //=>CODE
}
public void sum(int num1,string str){
    //=>CODE
}
sum(12,23) //第一個
sum(12) //第二個
sum(12,'word') //第三個
JS中沒有相似於後臺嚴格意義上的重載,JS中若是方法名相同,最後只能保留一個(和實參沒有關係)
JS中的重載:同一個方法,經過傳遞實參的不一樣(arguments)咱們完成不一樣的功能,咱們把這個也理解爲重載
function sum(num1,num2){
    return num1+num2;
}
function sum(){
    var ary=Array.prototype.slice.call(arguments)
    return eval(ary.join('+'));
}
sum(10,20)
sum(10,20,30);// =>無論哪一次執行的都是第二個sum
無論是後臺語言仍是js都有重寫:子類重寫父類的方法

類的繼承

什麼是繼承?
子類繼承父類中的一些屬性和方法

1.原型繼承webstorm

讓子類的原型指向父類的實例
Children.prototype=new Parent();
function Parent(){
    this.x=10;
}
Parent.prototype.getX=function(){
    console.log(this.x)
}

function Child(){

    this.y=20;
}
Child.prototype=new Parent(); //最好都在擴展子類原型方法以前執行
Child.prototype.constructor=Child;
Child.prototype.getY=function(){
    console.log(this.y);
}
var child=new Child();
console.log(child.y);
child.getY();
child.getX()
console.log(child.x);

clipboard.png

[細節]
1.咱們首先讓子類的原型指向父類的實例,而後再向子類原型上擴展方法,防止提早增長方法,等原型從新指向後,以前在子類原型上擴展的方法失效(子類原型已經指向新的空間地址了)
2.讓子類原型從新指向父類實例,子類原型上原有的constructor就沒有了,爲了保證構造函數的完整性,咱們最好給子類的原型從新設置constructor屬性值: Children.prototype.constructor=Children
[原理]
原型繼承,並非把父類的屬性和方法copy一份給子類,而是讓子類的原型和父類原型之間搭建一個連接的橋樑,之後子類或者子類的實例能夠經過原型鏈的查找機制,找到父類原型上的方法,從而調取這些方法使用便可。

[特徵]
子類不只能夠繼承父類原型上的公有屬性方法,並且父類提供給實例的那些私有屬性的方法,也被子類繼承了(存放在子類原型上,做爲子類公有的屬性和方法)編程語言

2.call繼承函數

在子類的構造體中,把父類作普通方法執行,讓父類方法中this指向子類的實例
function Parent(){
    this.x=10;
}
Parent.prototype.getX=function(){
    console.log(this.x);
}
function Children(){
    //=>this:child 子類的實例
    Parent.call(this); //讓Parent執行,方法中的this依然是子類中的實例(在父類構造體中寫this.xxx=xxx都至關於給子類的實例增長一些私有的屬性和方法)
    this.y=20;
}
var child=new Children();
console.log(child.x);
【原理】
把父類構造體中私有的屬性和方法,原封不動複製了一份給子類的實例(繼承完成後,子類和父類是沒有關係的);公有的沒法繼承。

【細節】
咱們通常把call繼承放在子類構造體的第一行,也就是建立子類實例的時候,進來的第一件事就是先繼承,而後再給實例賦值本身私有的(好處:本身的能夠把繼承過來的結果替換掉--若是有重複的狀況下)oop

3.寄生組合繼承學習

Object.create: 建立一個空對象,把obj做爲新建立對象的原型 低版本不兼容
var obj={name:'hello word'}
var newObj=Object.create(obj);
newObj.__proto__===obj
寄生組合式繼承完成了一個需求
子類公有的繼承父類公有的(原型繼承的變通)
子類私有的繼承父類私有的(call繼承完成)
function Parent(){
    this.x=10;
}
Parent.prototype.getX=function(){
    console.log(this.x)
}
function Children(){
    Parent.call(this)
    this.y=20;
}
Children.prototype=Object.create(Parent.prototype);
Children.prototype.constructor=Children;
Children.getY=function(){
    console.log(this.y);
}
var child=new Children();
console.log(child.x);
child.getX()

clipboard.png


本身實現一個相似於Objcet.create的方法
Object.myCreate=function myCreate(obj){
    var Fn=new Function();
    Fn.prototype=obj;
    return new Fn();
}
var oo={name:'o'}
Object.myCreate(oo)

4.ES6中的類和繼承

class Fn{
    constructor(a){
        //=>constructor:Fn
        //=>這裏面的this.xxx=xxx是給當前實例設置的私有屬性
        this.xxx=a
    }
    //=>這裏設置的方法都放在Fn.prototype上(給實例提供的公有屬性方法)    
    //=>getX $ setX:都是給Fn.prototype設置方法
    getx(){

    }
    setX(){

    }
    //=>static 這些屬性和方法都是Fn當作普通對象設置的私有屬性和方法,和實例沒有任何的關係
    static private(){

    }
}
let f=new Fn(10,20);

繼承

class A{
    constructor(){
        this.x=10
    }
    getX(){
        console.log(this.x);
    }
}

class B extends A{
    constructor(){
        super(); //=>原理call繼承, 第一句必須寫上super() 
        this.y=20;
    }
    getY(){
        console.log(this.y);
    }
}
let b=new B();

5.for in循環遍歷細節問題

Object.prototype.hasPubProperty=function hasPubProperty(){

}
/*
* for in循環 不只能夠遍歷當前對象(或者當前實例)全部的私有屬性和方法,還能夠把原型上本身建立的公共屬性方法進行遍歷
*
* for 只會遍歷私有的屬性和方法(更多的是索引),本身在原型上擴展的方法不會被遍歷出來
* */

var obj={name:'tom',age:8}
for (const objKey in obj) { //webstorm 快捷鍵 itin
    if(obj.hasOwnProperty(objKey)){
        console.log(objKey);
    }
    // console.log(objKey); // hasPubProperty
}
var ary=[12,23,34];
for (let i = 0; i < ary.length; i++) {
    console.log(ary[i]);
}

for (const aryKey in ary) { //快捷鍵 itar
    console.log(ary[aryKey]);
}
webStorm本身配置快捷鍵 file-> setting->liveTemplates 右側+本身DIY
相關文章
相關標籤/搜索