JavaScript高级笔记_002_构造函数和原型
JavaScript高級筆記_002_構造函數和原型
- 構造函數和原型
- 構造函數和原型
- 概述
- 構造函數
- 構造函數的問題
- 構造函數原型`prototype`
- 對象原型`__proto__` (四個下劃線)
- `constructor` 構造函數
- 構造函數,實例,原型對象三者之間的關系
- 原型鏈
- `Javascript` 的成員查找機制(規則)
- 原型對象`this` 指向
- 擴展內置對象
- 繼承
- `call()`
- 借用構造函數繼承父類型屬性
- 借用原型對象繼承父類型方法
- ES5中的新增方法
- ES5新增了一些方法,可以很方便的操作數組或者字符串,這些方法主要包括:
- 數組方法
- 查詢商品案例
- 字符串方法
- 對象方法
構造函數和原型
課程鏈接:
https://www.bilibili.com/video/BV1KJ411x7X7?p=23
構造函數和原型
概述
在典型的OOP語言中(如Java),都存在類的概念,類就是對象的模板,對象就是類的實例,但在ES6之前,JS中并沒有引入類的概念
ES6,全稱ECMAscript6.0,2015.06發版。但是目前瀏覽器的JavaScript版本都是ES5版本,大多數的高版本的瀏覽器也支持ES6,不過只實現了ES6的部分特性和功能
在ES6之前,對象不是基于類創建的,而是一種成為構造函數的特殊函數來定義對象和他的特征
創建對象可以通過以下三種方式:
對象字面量
new Object()
自定義構造函數
function Star(uname, age) {this.uname = uname;this.age = age;this.sing = function() {console.log('我會唱歌');} }var ldh = new Star('劉德華', 18); ldh.sing();構造函數
構造函數是一種特殊的函數,主要用來初始化對象,即為對象成員變量賦初始值,它總與new 一起使用。我們可以把對象中的一些公共屬性和方法抽取出來,然后封裝到這個函數里面
在JS中,使用構造函數時要注意一下兩點:
new** 在執行時會做四件事情:**
javascript 的構造函數中可以添加一些成員,可以在構造函數本身上添加,也可以在構造函數內部的this 上添加。通過這兩種方式添加的成員,就分別成為靜態成員和實例成員
- 靜態成員:在構造函數本身上添加的成員稱為靜態成員,只能有構造函數本身來訪問
- 實例成員:在構造函數內部創建的成員稱為實例成員,只能由實例化的對象來訪問
構造函數的問題
構造函數方法很好用,但是存在內存浪費的問題
構造函數原型prototype
構造函數通過原型分配的函數是所有對象所共享的
Javascript規定,每一個構造函數都有一個prototype 屬性,指向另一個對象。注意這個prototype 就是一個對象,這個對象的所有屬性和方法,都會被構造函數所擁有
我們可以把那些不變的方法,直接定義在**prototype**對象上,這樣所有對象的實例就可以共享這些方法
語法:
function Star(uname, age) {this.uname = uname;this.age = age; }Star.prototype.sing = function() {console.log('我唱歌'); }問答?
原型是什么?
一個對象,我們稱prototype 為原型對象
原型的作用是什么?
共享方法
一般情況下,我們的公共屬性定義到構造函數里面,公共的方法我們就放到原型對象身上
對象原型__proto__ (四個下劃線)
對象都會有一個屬性__proto__ 指向構造函數的prototype 原型對象,之所以我們對象可以使用構造函數prototype 原型對象的屬性和方法,就是因為對象有__proto__ 原型的存在
- __proto__ 對象原型和原型對象prototype 是等價的
- __proto__ 對象原型的意義就在于為對象的查找機制提供了一個方向,或者說一條路線,但是他是一個非標準屬性,因此在實際開發中,不可以使用這個屬性,它只是內部指向原型對象prototype
方法的查找規則:首先看對對象身上是否有這個方法,如果有就執行這個對象上的方法,如果沒有這個方法,因為__proto__ 的存在,就去構造函數原型對象prototype 身上去查找這個方法
constructor 構造函數
對象原型__proto__ 和構造函數prototype原型對象里面都有一個屬性constructor 屬性,constructor 我們稱為構造函數,因為它指向構造函數本身
constructor 主要用于記錄該對象引用于哪個構造函數,它可以讓原型對象重新指向原來的構造函數
function Star(uname, age) {this.name = uname;this.age = age; } Star.prototype.sing = function() {console.log('我會唱歌'); }; Star.prototype.movie= function() {console.log('我會演電影'); } var ldh = new Star(); console.log(ldh.__proto__.constructor); console.log(Star.prototype.constructor);很多情況下,我們需要手動的利用constructor 這個屬性指回原來的構造函數
function Star(uname, age) {this.name = uname;this.age = age; } Star.prototype = {// 如果我們修改了原來原型對象,給原型對象賦值的是一個對象,則必須手動利用constructor指回原來的構造函數// 手動的利用constructor 這個屬性指回原來的構造函數constructor : Star;sing : function() {console.log('我會唱歌');},movie : function() {console.log('我會演電影');} }var ldh = new Star(); console.log(ldh.__proto__.constructor); console.log(Star.prototype.constructor);如果我們修改了原來原型對象,給原型對象賦值的是一個對象,則必須手動利用constructor指回原來的構造函數
構造函數,實例,原型對象三者之間的關系
原型鏈
Javascript 的成員查找機制(規則)
原型對象this 指向
擴展內置對象
可以通過原型對象,對原來的內置對象進行擴展定義的方法。比如給數組增加自定義求和的功能
Array.prototype.sum = function() {for(var i = 0; i < this.length; i++) {var sum = 0;sum += this[i];}return sum; }var arr = [1,2,3]; console.log(arr.sum());數組和字符串內置對象不能給原型對象覆蓋操作Array.prototype = {} ,只能是Array.prototype.xxx = function() {} 的方式
繼承
ES6之前并沒有給我們提供extends 繼承。我們可以通過構造函數 + 原型對象模擬實現繼承,被稱為組合繼承
call()
調用這個函數并且修改函數運行時的this 指向
語法
fun.call(thisArg, arg1, arg2, ...);參數:
- thisArg:當前嗲用函數this的指向對象
- arg1, arg2:傳遞的其他參數
借用構造函數繼承父類型屬性
核心原理:通過call() 把父類型的this 指向子類型的this ,這樣就可以實現子類型繼承父類型的屬性
// 借用父構造函數繼承屬性 // 1 父構造函數 function Father(uname, age) {// this指向父構造函數的對象實例this.uname = uname;this.age = age; } // 2 子構造函數 function Son(uname, age, score) {// this指向子構造函數的對象實例Father.call(this, uname, age);this.score = score; }var son = new Son('劉德華'); console.log(son);借用原型對象繼承父類型方法
// 借用父構造函數繼承屬性 // 1 父構造函數 function Father(uname, age) {// this指向父構造函數的對象實例this.uname = uname;this.age = age; } Father.prototype.money = function() {console.log(100000); } // 2 子構造函數 function Son(uname, age, score) {// this指向子構造函數的對象實例Father.call(this, uname, age);this.score = score; }// 核心代碼 Son.prototype = new Father(); Son.prototype.constructor = Son;Son.prototype.exam = function() {conle.log('我要考試'); }var son = new Son('劉德華'); console.log(son);ES5中的新增方法
ES5新增了一些方法,可以很方便的操作數組或者字符串,這些方法主要包括:
- 數組方法
- 字符串方法
- 對象方法
數組方法
迭代(遍歷)方法:forEach(), map(), filter(), some() ,every();
forEach** 語法**
array.forEach(function(currentValue, index, arr));參數:
- currentValue :數組當前項的值
- index :數組當前項的索引
- arr :數組對象本身
例子:
var arr = [1,2,3]; var sum = 0; arr.forEach(function(value, index, array) {sum += value; });filter() ** 語法**
array.filter(function(currentValue, index, arr));- filter() 方法創建一個新的數組,新的數組中的元素是通過檢查指定數組中符合條件的所有元素,主要用于篩選數組
- 注意它返回的是一個新的數組
- currentValue :數組當前項的值
- index :數組當前項的索引
- arr :數組對象本身
some()** 語法**
array.some(function(currentValue, index, arr));- some() 方法用于檢測數組中的元素是否滿足指定條件。通俗點講就是查找數組中是否有滿足條件的元素
- 注意它返回的是布爾值,如果查找到這和個元素,就返回true ,如果找不到就返回false
- 如果找到第一個滿足條件的元素,則終止循環,不再繼續尋找
- currentValue :數組當前項的值
- index :數組當前項的索引
- arr :數組對象本身
查詢商品案例
字符串方法
tirm() 方法會從一個字符串的兩段刪除空白字符
語法
str.trim();tirm() 方法并不影響原字符串本身,它返回的是一個新的字符串
對象方法
Object.keys() 用于獲取自身對象的所有的屬性
語法
- 效果類似for…in
- 返回一個由屬性名組成的數組
Object.defineProperty() 定義對象中新屬性或修改原有的屬性
語法
- obj:必需。目標對象
- prop:必需。徐定義或修改的屬性的名字
- descriptor:必需。目標屬性所擁有的特性,以對象形式{}書寫
- value:設置屬性的值,默認為undefined
- writable:值是否可以重寫。true|false,默認為false
- enumerable:目標屬性是否可以被枚舉。true|false,默認為false
- configurable:目標屬性是都可以被刪除或者是否可以再次修改特性ture|false,默認為false
總結
以上是生活随笔為你收集整理的JavaScript高级笔记_002_构造函数和原型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JAVA文件传输原理及介绍—狂神说
- 下一篇: java 获取周六周日_JS实现获取当前