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