最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript面向對象核心知識與概念歸納整理

 更新時間:2020年05月09日 09:17:16   作者:杜尼卜  
這篇文章主要介紹了JavaScript面向對象核心知識與概念,整理總結了JavaScript面向對象程序設計中基本概念、原理與操作注意事項,需要的朋友可以參考下

本文實例講述了JavaScript面向對象核心知識與概念。分享給大家供大家參考,具體如下:

一、面向對象

1.1 概念

  1. 面向對象就是使用對象。面向對象開發(fā)就是使用對象開發(fā)。
  2. 面向過程就是用過程的方式進行開發(fā)。面向對象是對面向過程的封裝。

1.2 三大特性

抽象性
所謂的抽象性就是:如果需要一個對象描述數(shù)據(jù),需要抽取這個對象的核心數(shù)據(jù)

  1. 提出需要的核心屬性和方法
  2. 不在特定的環(huán)境下無法明確對象的具體意義

封裝性
對象是將數(shù)據(jù)與功能組合到一起,即封裝

  1. JS對象就是鍵值對的集合,鍵值如果是數(shù)據(jù)(基本數(shù)據(jù)、符合數(shù)據(jù)、空數(shù)據(jù))就稱為屬性,如果鍵值是函數(shù)那么就稱為方法
  2. 對象就是將屬性與方法封裝起來
  3. 方法是將過程封裝起來

繼承性
所謂繼承性就是自己沒有但是別人有,拿過來成為自己的,就是繼承,繼承是實現(xiàn)復用的一種手段

  • 在Java等語言中繼承滿足一個class的規(guī)則,類是一個class,他規(guī)定了一個對象有什么屬性和方法。
  • 在這些語言中繼承是class之間的繼承,一個class繼承另一個class,那么該class就有了另一個class的成員,那么由該class創(chuàng)建出來的對象就同時具有兩個class的成員。

在JS中沒有明確的繼承語法(ES6提供了class extend語法),一般都是按照繼承的理念實現(xiàn)對象的成員擴充實現(xiàn)繼承,因此JS中實現(xiàn)繼承的方法非常對多。

傳統(tǒng)繼承基于類,JS繼承基于對象

一個簡單的繼承模式:混入(mix)

function mix ( o1, o2 ) {
 for ( var k in o2 ) {
  o1[ k ] = o2[ k ];
 }
}

1.3 關于面向對象的一些其他概念

類class:在JS中就是構造函數(shù)

  • 在傳統(tǒng)的面向對象語言中,使用一個叫類的東西定義模板,然后使用模板創(chuàng)建對象。
  • 在構造方法中也具有類似的功能,因此也稱其為類

實例(instance)與對象(object)

  • 實例一般是指某一個構造函數(shù)創(chuàng)建出來的對象,我們稱為XXXX 構造函數(shù)的實例
  • 實例就是對象。對象是一個泛稱
  • 實例與對象是一個近義詞

鍵值對與屬性和方法

  • 在JS中鍵值對的集合稱為對象
  • 如果值為數(shù)據(jù)(非函數(shù)),就稱該鍵值對為屬性
  • 如果值為函數(shù)(方法),就稱該鍵值對為方法method

父類與子類(基類和派生類)

  • 傳統(tǒng)的面向對象語言中使用類來實現(xiàn)繼承那么就有父類、子類的概念
  • 父類又稱為基類,子類又稱為派生類
  • 在JS中沒有類的概念,在JS中常常稱為父對象,子對象,基對象,派生對象。

二、構造函數(shù)

2.1 構造函數(shù)是干什么用的

  1. 初始化數(shù)據(jù)的
  2. 在JS中給對象添加屬性用的,初始化屬性值用的

2.2 創(chuàng)建對象的過程

  1. 代碼:var p = new Person();
  2. 首先運算符new創(chuàng)建了一個對象,類似于{},是一個沒有任何(自定義)成員的對象。

    • 使用new 創(chuàng)建對象,那么對象的類型就是創(chuàng)建他的構造函數(shù)名
    • 使用{}無論如何都是Object類型,相當于new Object
  3. 然后調用構造函數(shù),為其初始化成員

    • 構造函數(shù)在調用的一開始,有一個賦值操作,即this = 剛剛創(chuàng)建出來的對象。
    • 因此在構造函數(shù)中this表示剛剛創(chuàng)建出來的對象。
  4. 在構造函數(shù)中 利用 對象的動態(tài)特性 為其對象添加成員。

三、作用域

3.1 什么是作用域

域表示的就是范圍,即作用域,就是一個名字在什么地方可以使用,什么時候不能使用。
簡單的說,作用域是針對變量的,比如我們創(chuàng)建一個函數(shù) a1,函數(shù)里面又包了一個子函數(shù) a2

// 全局作用域
functiona a1() {
 // a1作用域
 function a2() {
  // a2作用域
 }
}

此時就存 在三個作用域:全局作用域,a1 作用域,a2 作用域;即全局作用域包含了 a1 的作用域,a2 的作用域包含了 a1 的作用域。

a2 在查找變量的時候會先從自身的作用域區(qū)查找,找不到再到上一級 a1 的作用域查找,如果還沒找到就
到全局作用域區(qū)查找,這樣就形成了一個作用域鏈。

3.2 JS中詞法作用域的規(guī)則

  1. 函數(shù)允許訪問函數(shù)外部的數(shù)據(jù)
  2. 整個代碼結構中只有函數(shù)可以限定作用域
  3. 作用規(guī)則首先使用提升規(guī)則分析
  4. 如果當前作用域中有了名字了,就不考慮外面的名字

3.3 屬性搜索原則

  • 所謂的屬性搜索原則,就是對象在訪問屬性或方法的時候,首先在當前對象中查找
  • 如果當前對象中存儲著屬性或方法,停止查找,直接使用該屬性或方法
  • 如果當前對象沒有該成員,那么再在其原型對象中查找
  • 如果原型對象中含有該成員,那么停止查找,直接使用
  • 如果原型中還沒有,就到原型的原型中查找
  • 如此往復,直到Object.protitype還沒有,那么就返回undefined
  • 如果是調用方法就報錯,該xxx不是一個函數(shù)

四、閉包

4.1 說說你對閉包的理解

實用閉包主要是為了設計私有方法和變量。閉包的優(yōu)點是可以避免全局變量的污染;缺點是閉包會常駐內存,增加內存使用量,使用不當很容易造成內存泄露。在JavaScript中,函數(shù)即閉包,只有函數(shù)才能產生作用域。

閉包有3個特性:

  1. 函數(shù)嵌套函數(shù)
  2. 在函數(shù)內部可以引用外部的參數(shù)和變量
  3. 參數(shù)和變量不會以垃圾回收機制回收

4.2 閉包有什么用(特性)

閉包的作用,就是保存自己私有的變量,通過提供的接口(方法)給外部使用,但外部不能直接訪問該變量。
通過使用閉包,我們可以做很多事情,比如模擬面向對象的代碼風格;更優(yōu)雅,更簡潔的表達出代碼;在某些方面提升代碼的執(zhí)行效率。利用閉包可以實現(xiàn)如下需求:

  1. 匿名自執(zhí)行函數(shù)

一個匿名的函數(shù),并立即執(zhí)行它,由于外部無法引用它內部的變量,因此在執(zhí)行完后很快就會被釋放,關鍵是這種機制不會污染全局對象。

  1. 緩存

閉包正是可以做到這一點,因為它不會釋放外部的引用,從而函數(shù)內部的值可以得以保留。

  1. 實現(xiàn)封裝
  2. 模擬面向對象的代碼風格

4.3 閉包的基本模型

對象模式
函數(shù)內部定義個一個對象,對象中綁定多個函數(shù)(方法),返回對象,利用對象的方法訪問函數(shù)內的數(shù)據(jù)

function createPerson() {
 var __name__ = "";
 return {
  getName: function () {
   return __name__;
  },
  setName: function( value ) {
   // 如果不姓張就報錯
   if ( value.charAt(0) === '張' ) {
    __name__ = value;
   } else {
    throw new Error( '姓氏不對,不能取名' );
   }
  }
 }
}
var p = createPerson();
p.set_Name( '張三豐' );
console.log( p.get_Name() );
p.set_Name( '張王富貴' );
console.log( p.get_Name() );

函數(shù)模式
函數(shù)內部定義一個新函數(shù),返回新函數(shù),用新函數(shù)獲得函數(shù)內的數(shù)據(jù)

function foo() {
 var num = Math.random();
 function func() {
  return mun;
 }
 return func;
}
var f = foo();
// f 可以直接訪問這個 num
var res1 = f();
var res2 = f();

沙箱模式
沙箱模式就是一個自調用函數(shù),代碼寫到函數(shù)中一樣會執(zhí)行,但是不會與外界有任何的影響,比如jQuery

(function () {
 var jQuery = function () { // 所有的算法 }
 // .... // .... jQuery.each = function () {}
 window.jQuery = window.$ = jQuery;
})();
$.each( ... )

4.4 閉包的性能問題

js 垃圾回收機制,也就是當一個函數(shù)被執(zhí)行完后,其作用域會被收回,如果形成了閉包,執(zhí)行完后其作用域就不會被收回。

函數(shù)執(zhí)行需要內存,那么函數(shù)中定義的變量,會在函數(shù)執(zhí)行結束后自動回收,凡是因為閉包結構的,被引出的數(shù)據(jù),如果還有變量引用這些數(shù)據(jù)的話,那么這些數(shù)據(jù)就不會被回收。因此在使用閉包的時候如果不使用某些數(shù)據(jù)了,一定要賦值一個null

var f = (function () {
 var num = 123;
 return function () {
  return num;
 };
})();
// f 引用著函數(shù),函數(shù)引用著變量num
// 因此在不使用該數(shù)據(jù)的時候,最好寫上
f = null;

五、原型

5.1 什么是原型

一句話說明什么是原型:原型能存儲我們的方法,構造函數(shù)創(chuàng)建出來的實例對象能夠引用原型中的方法。

JS中一切皆對象,而每個對象都有一個原型(Object除外),這個原型,大概就像Java中的父類,所以,基本上你可以認為原型就是這個對象的父對象,即每一個對象(Object除外)內部都保存了它自己的父對象,這個父對象就是原型。一般創(chuàng)建的對象如果沒有特別指定原型,那么它的原型就是Object(這就很類似Java中所有的類默認繼承自Object類)。

ES6通過引入class ,extends等關鍵字,以一種語法糖的形式把構造函數(shù)包裝成類的概念,更便于大家理解。是希望開發(fā)者不再花精力去關注原型以及原型鏈,也充分說明原型的設計意圖和類是一樣的。

5.2 查看對象的原型

當對象被創(chuàng)建之后,查看它們的原型的方法不止一種,以前一般使用對象的__proto__屬性,ES6推出后,推薦用Object.getPrototypeOf()方法來獲取對象的原型

function A(){
 this.name='lala';
}
var a=new A();
console.log(a.__proto__) 
//輸出:Object {}
 
//推薦使用這種方式獲取對象的原型
console.log(Object.getPrototypeOf(a)) 
//輸出:Object {}

無論對象是如何創(chuàng)建的,默認原型都是Object,在這里需要提及的比較特殊的一點就是,通過構造函數(shù)來創(chuàng)建對象,函數(shù)A本身也是一個對象,而A有兩個指向表示原型的屬性,分別是__proto__prototype,而且兩個屬性并不相同

function A(){
 this.name='lala';
}
var a=new A();
console.log(A.prototype) 
//輸出:Object {}
 
console.log(A.__proto__) 
//輸出:function () {}
console.log(Object.getPrototypeOf(A))
//輸出:function () {}

函數(shù)的的prototype屬性只有在當作構造函數(shù)創(chuàng)建的時候,把自身的prototype屬性值賦給對象的原型。而實際上,作為函數(shù)本身,它的原型應該是function對象,然后function對象的原型才是Object。

總之,建議使用ES6推薦的查看原型和設置原型的方法。

5.3 原型的用法

其實原型和類的繼承的用法是一致的:當你想用某個對象的屬性時,將當前對象的原型指向該對象,你就擁有了該對象的使用權了。

function A(){
 this.name='world ';
}
function B(){
 this.bb="hello"
}
var a=new A();
var b=new B();

//將b設置為a的原型,此處有一個問題,即a的constructor也指向了B構造函數(shù),可能需要糾正 
Object.setPrototypeOf(a,b);
a.constructor=A;
console.log(a.bb); //hello

如果使用ES6來做的話則簡單許多,甚至不涉及到prototype這個屬性

class B{
  constructor(){
   this.bb='hello'
  }
}
class A extends B{
  constructor(){
  super();
  this.name='world';
  }
}
 
var a=new A();
console.log(a.bb+" "+a.name); //hello world
console.log(typeof(A))    //"function"

怎么樣?是不是已經完全看不到原型的影子了?活脫脫就是類繼承,但是你也看得到實際上類A 的類型是function,所以說,本質上class在JS中是一種語法糖,JS繼承的本質依然是原型,不過,ES6引入classextends 來掩蓋原型的概念也是一個很友好的舉動,對于長期學習那些類繼承為基礎的面對對象編程語言的程序員而言。

我的建議是,盡可能理解原型,盡可能用class這種語法糖。

好了,問自己兩個問題:

  1. 為什么要使用原型?——提高函數(shù)的復用性。
  2. 為什么屬性不放在原型上而方法要放在原型上?

    • 利用對象的動態(tài)特性:構造函數(shù).prototype.xxxx = vvv
    • 利用直接替換
    Student.prototype = {
    sayHello : function(){},
    study : function(){}
    };

5.4 原型鏈

什么是原型鏈?
凡是對象就有原型,那么原型又是對象,因此凡是給定一個對象,那么就可以找到他的原型,原型還有原型,那么如此下去,就構成一個對象的序列,稱該結構為原型鏈。

每個實例對象都有一個__proto_屬性,該屬性指向它原型對象,這個實例對象 的構造函數(shù)有一個原型屬性 prototype,與實例的__proto__屬性指向同一個對象。當一個對象在查找一個屬性的時, 自身沒有就會根據(jù)__proto__ 向它的原型進行查找,如果都沒有,則向它的原型的原型繼續(xù)查找,直到查到 Object.prototype._proto_null,這樣也就形成了原型鏈

這個概念其實也變得比較簡單,可以類比類的繼承鏈條,即每個對象的原型往上追溯,一直到Object為止,這組成了一個鏈條,將其中的對象串聯(lián)起來,當查找當前對象的屬性時,如果沒找到,就會沿著這個鏈條去查找,一直到Object,如果還沒發(fā)現(xiàn),就會報undefined。

原型鏈的結構
凡是使用構造函數(shù),創(chuàng)建出對象,并且沒有利用賦值的方式修改原型,就說該對象保留默認的原型鏈。
默認原型鏈結構是什么樣子呢?

function Person(){}
var p = new Person();
//p 具有默認的原型鏈

默認的原型鏈結構就是:當前對象 -> 構造函數(shù).prototype -> Object.prototype -> null

在實現(xiàn)繼承的時候,有時候會利用替換原型鏈結構的方式實現(xiàn)原型繼承,那么原型鏈結構就會發(fā)生改變

function DunizbCollection(){}
DunizbCollection.prototype = [];
var arr = new DunizbCollection();

此時arr對象的原型鏈結構被指向了數(shù)組對象的原型鏈結構了:arr -> [] -> Array.prototype -> Object.prototype -> null

用圖形表示對象的原型鏈結構
以如下代碼為例繪制原型鏈結構

function Person(){}
var p = new Person();

原型鏈結構圖為:

使用原型需要注意兩點:

  1. 原型繼承鏈條不要太長,否則會出現(xiàn)效率問題。
  2. 指定原型時,注意constructor也會改變。

六、繼承

實現(xiàn)繼承有兩種常見方式:

6.1 混合式繼承

最簡單的繼承就是將別的對象的屬性強加到我身上,那么我就有這個成員了。
混合式繼承的簡單描述:

function Person() {};
Person.prototype.extend = function ( o ) {
  for ( var k in o ) {
   this[ k ] = o[ k ];
  }
};
Person.prototype.extend({
  run: function () { console.log( '我能跑了' ); },
  eat: function () { console.log( '我可以吃了' ); },
  sayHello: function () { console.log( '我吃飽了' ); }
});

6.2 原型繼承

利用原型也可以實現(xiàn)繼承,不需要在我身上添加任何成員,只要原型有了我就有了。

6.3 借用構造函數(shù)繼承

這種技術的基本思想相當簡單,即在子類型構造函數(shù)的內部調用超類型構造函數(shù),而函數(shù)只不過是在特定環(huán)境中執(zhí)行代碼的對象,因此通過使用apply()call()方法也可以在(將來)新創(chuàng)建的對象上執(zhí)行構造函數(shù)

function Person ( name, age, gender ) {
  this.name = name;
  this.age = age;
  this.gender = gender;
}
// 需要提供一個 Student 的構造函數(shù)創(chuàng)建學生對象
// 學生也應該有 name, age, gender, 同時還需要有 course 課程
function Student ( name, age, gender, course ) {
  Person.call( this, name, age, gender );
  this.course = course;
}

在《JavaScript高級程序設計(第三版)》中詳細介紹了繼承的6種方式

七、函數(shù)的四種調用模式

7.1 函數(shù)模式

就是一個簡單的函數(shù)調用。函數(shù)名的前面沒有任何引導內容。

function foo () {}
var func = function () {};
...
foo();
func();
(function () {} )();

this 的含義:在函數(shù)中 this 表示全局對象,在瀏覽器中式 window

7.2 方法模式

方法一定式依附與一個對象,將函數(shù)賦值給對象的一個屬性,那么就成為了方法。

function f() {
 this.method = function () {};
}
var o = {
 method: function () {}
}

this 的含義:這個依附的對象

7.3 構造器調用模式

創(chuàng)建對象的時候構造函數(shù)做了什么?由于構造函數(shù)只是給 this 添加成員,沒有做其他事情。而方法也可以完成這個操作,就是 this 而言,構造函數(shù)與方法沒有本質的區(qū)別。

特征:

  1. 使用 new 關鍵字,來引導構造函數(shù)。
  2. 構造函數(shù)中的 this 與方法中的一樣,表示對象,但是構造函數(shù)中的對象是剛剛創(chuàng)建出來的對象
  3. 構造函數(shù)中不需要 return ,就會默認的 return this。

    • 如果手動添加return ,就相當于 return this
    • 如果手動的添加 return 基本類型,無效,還是保留原來 返回 this
    • 如果手動添加的 return null,或 return undefined ,無效
    • 如果手動添加 return 對象類型,那么原來創(chuàng)建的 this 就會被丟掉,返回的是 return 后面的對象

7.4 上下文調用模式

上下文就是環(huán)境。就是自己定義設置 this 的含義。

語法

  1. 函數(shù)名.apply( 對象, [ 參數(shù) ] );
  2. 函數(shù)名.call( 對象, 參數(shù) );

描述

  1. 函數(shù)名就是表示函數(shù)本身,使用函數(shù)進行調用的時候默認 this 是全局變量
  2. 函數(shù)名也可以是方法提供,使用方法調用的時候,this 是指向當前對象
  3. 使用 apply 進行調用后,無論是函數(shù)還是方法都無效了,我們的 this ,由 apply 的第一個參數(shù)決定

參數(shù)問題
無論是 call 還是 apply 在沒有后面的參數(shù)的情況下(函數(shù)無參數(shù),方法五參數(shù))是完全一致的

function foo(){
 console.log( this );
}
foo.apply( obj );
foo.call( obj );

第一個參數(shù)的使用也是有規(guī)則的:

  • 如果傳入的是一個對象,那么就相當于設置該函數(shù)中的 this 為參數(shù)
  • 如果不傳入?yún)?shù),或傳入 nullundefined 等,那么相當于 this 默認為 window
foo();
foo.apply();
foo.apply( null );
  • 如果傳入的是基本類型,那么 this 就是基本類型對應的包裝類型的引用

在使用上下文調用的時候,原函數(shù)(方法)可能會帶有參數(shù),那么這個參數(shù)再上下文調用中使用 第二個(第 n 個)參數(shù)來表示

function foo( num ) {
 console.log( num );
}
foo.apply( null, [ 123 ] );
// 等價于
foo( 123 );

參考資料

感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運行工具http://tools.jb51.net/code/HtmlJsRun測試上述代碼運行效果。

更多關于JavaScript相關內容感興趣的讀者可查看本站專題:《javascript面向對象入門教程》、《JavaScript錯誤與調試技巧總結》、《JavaScript數(shù)據(jù)結構與算法技巧總結》、《JavaScript遍歷算法與技巧總結》及《JavaScript數(shù)學運算用法總結

希望本文所述對大家JavaScript程序設計有所幫助。

相關文章

  • js鏈接確認提醒功能

    js鏈接確認提醒功能

    非常不錯的功能,當單機一個鏈接時,會彈出確認對話框效果
    2008-09-09
  • 使用uni-app開發(fā)微信小程序的實現(xiàn)

    使用uni-app開發(fā)微信小程序的實現(xiàn)

    這篇文章主要介紹了使用uni-app開發(fā)微信小程序的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-12-12
  • loading動畫特效小結

    loading動畫特效小結

    本篇文章主要分享了javascript實現(xiàn)loading動畫特效的示例代碼。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-01-01
  • Layui 設置select下拉框自動選中某項的方法

    Layui 設置select下拉框自動選中某項的方法

    今天小編就為大家分享一篇Layui 設置select下拉框自動選中某項的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-08-08
  • 完美兼容各大瀏覽器獲取HTTP_REFERER方法總結

    完美兼容各大瀏覽器獲取HTTP_REFERER方法總結

    發(fā)現(xiàn)一個關于瀏覽器兼容的問題,當用JS 執(zhí)行代碼 window.location.href=”http://m.fzitv.net” 來進行跳轉的時候,F(xiàn)irefox 可以獲取到到HTTP_REFERER頁面,但是在IE中這一項為空
    2014-06-06
  • JS實現(xiàn)不使用圖片仿Windows右鍵菜單效果代碼

    JS實現(xiàn)不使用圖片仿Windows右鍵菜單效果代碼

    這篇文章主要介紹了JS實現(xiàn)不使用圖片仿Windows右鍵菜單效果代碼,涉及文鼎字及css樣式的使用技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-10-10
  • Bootstrap Table 刪除和批量刪除

    Bootstrap Table 刪除和批量刪除

    這篇文章主要介紹了Bootstrap Table 刪除和批量刪除的相關資料,需要的朋友可以參考下
    2017-09-09
  • javascript 正則表達式(一)

    javascript 正則表達式(一)

    javascript 正則表達式使用實例,挺有意思的,既不是基礎也不是技巧就是解決例子。
    2010-05-05
  • 全面解析JavaScript 中 null

    全面解析JavaScript 中 null

    null 是一種原始類型,表示有意不包含任何對象值,在這篇文章中,你將學習關于 JavaScript 中的 null 的一切: 它的含義,如何檢測它,null 和 undefined 之間的區(qū)別,以及為什么大量使用 null 會造成代碼維護困難等,需要的朋友可以參考下
    2022-09-09
  • JavaScript實現(xiàn)九宮格點擊變色效果

    JavaScript實現(xiàn)九宮格點擊變色效果

    這篇文章主要為大家詳細介紹了JavaScript實現(xiàn)九宮格點擊變色效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08

最新評論

博爱县| 云浮市| 德安县| 桂阳县| 武威市| 灵山县| 元谋县| 峡江县| 如皋市| 马鞍山市| 石城县| 黎平县| 和林格尔县| 台东市| 安福县| 通山县| 乐亭县| 临洮县| 塔城市| 安康市| 姜堰市| 长海县| 辰溪县| 施秉县| 孟连| 买车| 仁怀市| 水城县| 平阴县| 五河县| 永州市| 呈贡县| 乌兰察布市| 精河县| 阿合奇县| 隆林| 济南市| 怀远县| 永胜县| 尼勒克县| 榆社县|