javascript
JavaScript从入门到放弃 - (一)构造函数和原型
目錄
- 1. 創建對象的三種方式
- 1.1 用字面量創建
- 1.2 用new關鍵字創建
- 1.3 借用構造函數創建
- 2. 實例成員和靜態成員
- 2.1 實例成員
- 2.2 靜態成員
- 3 構造函數原型
- 4 對象原型 __ proto__
- 5 constructor 構造函數
- 6 構造函數、實例、原型對象三者關系
- 7 原型鏈和成員的查找機制
- 7.1 原型鏈
- 7.2 查找機制
- 8 原型對象中的this指向
- 9 擴展內置對象
- 附 vs code的JavaScript語義檢查設置
1. 創建對象的三種方式
1.1 用字面量創建
var obj = {};1.2 用new關鍵字創建
var obj = new Object();- new執行做的四件事情:
1.3 借用構造函數創建
function Person(name,age){this.name = name;this.age = age; } var obj = new Person('zs',12);2. 實例成員和靜態成員
構造函數中的屬性和方法統稱為成員,成員又分為實例成員和靜態成員。
2.1 實例成員
定義:構造函數內部通過this添加的成員,;
比如1.3 構造函數中的Person里面的name、age。
注意:實例成員,只能通過實例化的對象來訪問
2.2 靜態成員
定義:直接在構造函數三身上添加的成員。
例如:
靜態成員,只能通過構造函數來訪問。
3 構造函數原型
構造函數方法雖然好用,但是存在浪費內存的問題。
如果希望所有對象使用同一個函數,需要做些什么呢?
答案是構造函數原型prototype
構造函數通過原型分配的函數是所有對象所共享的,這就意味著不用再單獨開辟內存空間。
JavaScript 規定,每一個構造函數都有一個 prototype 屬性,指向另一個對象。這個 prototype 就是一個對象,這個對象的所有屬性和方法,都會被構造函數所擁有。
因此,我們可以把某些固定的方法,直接定義在prototype對象上,這樣所有對象的實例就可以共享這些方法。
舉例說明:
這樣就實現了方法的共享,所有的實例都可以使用這個方法,不再另行開辟內存空間。
總結:
一般情況下,簡單數據類型的公共屬性放到構造函數里,復雜數據類型如公共方法放到原型對象上
4 對象原型 __ proto__
對象都有一個屬性__proto__ 指向構造函數的prototype原型對象,之所以對象可以使用構造函數prototype原型對象的屬性和方法,就是因為對象有__proto__原型存在。
__proto__對象原型和原型對象 prototype 是等價的;
__proto__對象原型的意義就在于為對象的查找機制提供一個方向,或者說一條路線。
方法的查找規則:
首先,,看對象身上是否有該方法,如果有就執行這個對象上的方法,如果沒有這個方法,因為有__proto__ 的存在,就去構造函數原型對象prototype上去查找方法。
等價驗證:
注意:
__proto__ 是一個非標準屬性,因此實際開發中,不可以直接用它來賦值等操作,它只是內部指向原型對象 prototype。
5 constructor 構造函數
對象原型( __proto__)和構造函數(prototype)原型對象里面都有一個屬性 constructor 屬性 ,constructor 我們稱為構造函數,因為它指回構造函數本身。
constructor 主要用于記錄該對象引用于哪個構造函數,它可以讓原型對象重新指向原來的構造函數。
一般情況下,對象的方法都在構造函數的原型對象中設置。如果有多個對象的方法,我們可以給原型對象采取對象形式賦值,但是這樣就會覆蓋構造函數原型對象原來的內容,這樣修改后的原型對象 constructor 就不再指向當前構造函數了。此時,我們可以在修改后的原型對象中,添加一個 constructor 指向原來的構造函數。
如果我們修改了原來的原型對象,給原型對象賦值的是一個對象,則必須手動利用constructor指回原來的構造函數(constructor: Person)。
function Star(uname, age) {this.uname = uname;this.age = age;}// 很多情況下,我們需要手動的利用constructor 這個屬性指回 原來的構造函數Star.prototype = {// 如果我們修改了原來的原型對象,給原型對象賦值的是一個對象,則必須手動的利用constructor指回原來的構造函數constructor: Star, // 手動設置指回原來的構造函數sing: function() {console.log('我會唱歌');},movie: function() {console.log('我會演電影');} } var zxy = new Star('張學友', 19); console.log(zxy)以上代碼運行結果,設置constructor屬性如圖:
constructor 主要用于記錄該對象引用于哪個構造函數,它可以讓原型對象重新指向原來的構造函數。
6 構造函數、實例、原型對象三者關系
7 原型鏈和成員的查找機制
7.1 原型鏈
只要是實例對象就有_proto__ 原型(屬性),指向的構造函數的原型對象,構造函數的原型對象也是一個對象,也有__proto__屬性,這樣一層一層往上找就形成了原型鏈。
Star 原型對象里面的__proto__ 原型指向的是Object.prototype
<script>function Star(uname, age) {this.uname = uname;this.age = age;}Star.prototype.sing = function() {console.log('我會唱歌');}var ldh = new Star('劉德華', 18);// 1、只要是對象就有__proto__,指向原型對象console.log(Star.prototype);// 2、Star原型對象里面的__proto__原型指向的是Object.prototypeconsole.log(Star.prototype.__proto__ === Object.prototype); //返回true// 3、我們Object.prototype原型對象里面的__proto__原型,指向為nullconsole.log(Object.prototype.__proto__); </script>7.2 查找機制
當訪問一個對象的屬性(包括方法)時,首先查找這個對象自身有沒有該屬性。
如果沒有就查找它的原型(也就是 __proto__指向的 prototype 原型對象)。
如果還沒有就查找原型對象的原型(Object的原型對象)。
依此類推一直找到 Object 為止(null)。
__proto__對象原型的意義就在于為對象成員查找機制提供一個方向,或者說一條路線。
8 原型對象中的this指向
構造函數中的this和原型對象的this,都指向new出來的實例對象。
function Star(uname, age) {this.uname = uname;this.age = age; } var that; Star.prototype.sing = function() {console.log('我會唱歌');that = this; } var ldh = new Star('劉德華', 18); // 1. 在構造函數中,里面this指向的是對象實例 ldh console.log(that === ldh);//true // 2.原型對象函數里面的this 指向的是 實例對象 ldh9 擴展內置對象
可以通過原型對象,對原來的內置對象的方法進行擴展自定義。比如給數據Array增加自定義求偶數和的功能。
console.log(Array.prototype);// 自定義一個求和的方法Array.prototype.sum = function() {sum = 0;for (var i = 0; i < this.length; i++) {sum += this[i];}return sum;}var arr = [1, 2, 3];console.log(arr.sum());附 vs code的JavaScript語義檢查設置
啟用或禁用JavaScript 文件的語義檢查,若有jsconfig.json 或 tsconfig.json 文件,將覆蓋此設置。
"javascript.implicitProjectConfig.checkJs": true,若要禁用語義檢查,則在js文件里加入// @ts-nocheck注釋
VS code 插件市場 https://marketplace.visualstudio.com/vscode
下一篇:JavaScript從入門到放棄 -(二)繼承
總結
以上是生活随笔為你收集整理的JavaScript从入门到放弃 - (一)构造函数和原型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小程序开发(3)-之wx.request
- 下一篇: Java-Super