JavaScript高級
數(shù)據(jù)類型
在JS中 字符串不只是字符串 還是一個對象
string類型
var str = 'xxxxxx';//一般聲明方式
var str2 = new String('yyyyyy');//底層原型聲明方式->對象
array類型(typeof為object) //萬物皆對象(函數(shù))
var arr = [1,2,3];//一般聲明方式
var arr2 = new Array();//底層原型聲明方式->對象
object類型
var obj = {};//一般聲明方式
var arr2 = new Object();//底層原型聲明方式->對象
構(gòu)造函數(shù)(本質(zhì)為自定義函數(shù))
區(qū)別:構(gòu)造函數(shù)與自定義函數(shù)唯一沒有意義的區(qū)別為構(gòu)造函數(shù)命名方式采用大駝峰
作用:一般用來構(gòu)建對象(通過
new
關(guān)鍵字實例化)如new String()
new Array()
//構(gòu)造函數(shù)
function Xiaohuwei(){
console.log('Hello world');
}
//自定義new一個女朋友對象
function Grilfriend(){
console.log('memeda');
}
//實例化
var gf = new Grilfriend();
判斷是否為真數(shù)組
var arr = [1,2,3];
通過instance關(guān)鍵字判斷//instanceof判斷原型對象是否一致(是否在一條原型鏈上)
console.log(arr instanceof Array)奠滑;//返回值為布爾
數(shù)組可以為數(shù)組或者對象 但是對象不能為數(shù)組
再分類
數(shù)組和對象統(tǒng)一為為引用類型
作用域問題
var str = 'xxxxxx';//全局(頂級)->所有區(qū)域都可使用
function memeda(){
var str2 = "yyyyy";//二級變量 作用域在memeda內(nèi)部
console.log(str);
function heheda(){
console.log(str);
console.log(str2);
}
heheda();
console.log(str2);
}
memeda();
作用域鏈:作用域的生效區(qū)間由外到內(nèi)延申 形成的作用域區(qū)間
函數(shù)閉包
也就是內(nèi)嵌函數(shù)
function son(){
var num = 1;//二級變量初始值
function getNum(){
num++;
return num;//將num的值反出去
}
return getNum;//將內(nèi)部嵌套的函數(shù)反出去
}
var getnums = son();//代理到了內(nèi)部嵌套函數(shù)
console.log(getnums());//第一次 2
console.log(getnums());//第二次 3
console.log(getnums());//第三次 4
var num = getnums()//第四次 5
console.log(num)//5
num = null //手動銷毀(置空)
console.log(getnums());//第五次 null
普通變量:用完被GC回收
閉包后的變量:保存在內(nèi)存中 不被銷毀 可以動態(tài)獲取到局部變量的值
過多的使用閉包會導(dǎo)致內(nèi)存泄露,可以手動銷毀(避免內(nèi)存泄漏)也就是手動置空
自調(diào)函數(shù)
var pras = "tom";
(function(val){
console.log('hello'+val);
})(pras)
永遠(yuǎn)自動執(zhí)行一次 在閉包可以被完美解析
閉包和自調(diào)函數(shù)應(yīng)用場景
已知頁面有諾干個
li
標(biāo)簽 點擊每一個彈出相應(yīng)的下標(biāo)
for(var i = 0; i<lilist.length;i++){
(function(){//自調(diào)函數(shù)
var id = i;//將i重新賦值給id 保存當(dāng)前i的值 之后與i無關(guān)
lilist[i].onclick=function(){
alert(id);//彈出上面保存過的i的值
}
})()
}
es6 可以用let聲明解決
變量提升
在js中 變量的聲明是最優(yōu)先的 賦值之類的操作按照正常程序從上至下
var
沒有塊級作用域 可以變量提升let
有塊級作用域 不存在提升
變量在使用過程中會使用就近原則
var memeda = 'xxxxxxx';
function heheda(){
console.log(memeda);//打印underifend 因為它最近作用域在函數(shù)內(nèi)部 而函數(shù)內(nèi)部只申明了還沒有賦值
var memeda = '100';
console.log(memeda)
}
JS面向?qū)ο?/h2>
本質(zhì)就是構(gòu)造函數(shù)
對象字面量
var obj = {};
//創(chuàng)建對象 封裝構(gòu)建函數(shù) 不能直接調(diào)用!需要通過new關(guān)鍵字
function User(userName,sex){
this.userName = userName;
this.sex = sex;
this.dosomething = function(){
console.log('i can singing....');
}
}
//調(diào)用
var stu = new User('么么噠','女');
console.log(stu.userName);
prototype |
顯示原型 只有構(gòu)造函數(shù)才具有 也是一個對象 具有隱式原型 |
---|---|
_proto_ |
隱式原型 只有對象才具有 |
constructor |
所有對象都具備該屬性 指向構(gòu)造函數(shù) |
一個對象的 __proto__
指向其構(gòu)造函數(shù)的 ptototype
既 User().__proto__ == User.prototype
有了顯示原型才有隱式原型
所有的隱式原型都不可用 ,一般用到的方法都是在用底層構(gòu)造函數(shù)的顯示原型伯襟,因為隱式原型繼承的是構(gòu)造函數(shù)的顯示原型茄蚯。所有對象的構(gòu)造函數(shù)(原型)都是
Object()
object的父構(gòu)造函數(shù)為空团赏。
繼承 Extends
將一些對象公有的屬性和方法挑選出來放到一個父原型里面
原型鏈直接繼承
人類
function Person(){
}
Person.prototype.man = '男'虑鼎;
Person.prototype.women = '女'瘤泪;
Person.prototype.eat = function(){
console.log("i can eat ...");
}
Lower.prototype = Person.prototype//原型鏈直接繼承
Lower.prototype.constructor = Lower//解決繼承鏈紊亂問題
程序員
function Lower(){
this.writeBug = function(){
console.log('i can just bug...')
}
}
var obj = new Lower();//會導(dǎo)致繼承鏈紊亂
console.log(obj);
直接繼承
公有手機原型
function Phone(color){
this.color=color;
this.playgame=function(){
console.log("i can playgames");
}
}
Huaweipro30.prototype = new Phone("black");//將華為的原型指向手機公有的原型 既繼承
華為手機
function Huaweipro30(color){
this.color=color;
this.hwx = function(){
console.log("hwx....");
}
}
//原型直接繼承
var hw = new Huaweipro30();//會導(dǎo)致繼承鏈紊亂
Huaweipro30.prototype.constructor = Huaweipro30;//解決繼承鏈紊亂問題
console.log(hw.color);//black
繼承鏈紊亂
使用上述實例化后
hw
對象的構(gòu)造函數(shù)指向Phone()
而不是指向Huaweipro30()
解決辦法如上
注意
數(shù)組和對象屬于引用類型不會重新開辟內(nèi)存谋右,如果用一個構(gòu)造函數(shù)實例化了兩個對象A 和B 硬猫,并且繼承方式采用上面任何一種,如果在對象A中改變了構(gòu)造函數(shù)的數(shù)組或者對象,那么改了之后相應(yīng)的數(shù)組或者對象在對象B中也會生效啸蜜,如果對象A修改了構(gòu)造函數(shù)的屬性(字符串)會重新開辟內(nèi)存坑雅,則不會影響對象B,只對A生效衬横。解決辦法就是改變繼承方式裹粤,使用構(gòu)造函數(shù)綁定解決。
構(gòu)造函數(shù)綁定 Call 和 Apply
所有函數(shù)的構(gòu)造方法(原型)為
Function
而該函數(shù)里面具有call()
和apply()
方法注意:這兩種方法只有構(gòu)造函數(shù)具有
作用:將一個構(gòu)造函數(shù)的實例對象賦值給另一個對象(對象復(fù)制)
一個參數(shù)實例
function User(){
this.userName = "張三"蜂林;
this.doing = function(){
console.log('i can liaomei...');
}
}
function Memeda(){
}
var obj = new Memeda();//用Memeda實例化
User.call(obj)//將User對象的屬性和方法復(fù)制給了obj
或者
User.apply(obj)
console.log(obj.userName)//張三
或者
function User(){
this.userName = "張三"遥诉;
this.doing = function(){
console.log('i can liaomei...');
}
}
function Memeda(){
//構(gòu)造函數(shù)綁定繼承
User.call(this);
}
var obj = new Memeda();
console.log(obj.userName)//張三
兩個參數(shù)實例->傳參問題
function User(userName,sex){
this.userName = userName;
this.sex = sex噪叙;
this.doing = function(){
console.log('i can liaomei...');
}
}
function Memeda(userName,sex){
//構(gòu)造函數(shù)綁定繼承
User.call(this,userName,sex);//參數(shù)傳遞匹配
或者
User.apply(this,[userName,sex]);
}
var obj = new Memeda('張三','女');
console.log(obj.userName)//張三
console.log(obj.sex)//女
call()
和apply()
的區(qū)別在構(gòu)造函數(shù)實例化過程中參數(shù)傳遞綁定的方式不一樣矮锈,如上代碼塊, 前者需要一行寫完构眯,后者只需要一個數(shù)組即可愕难。
ES6面向?qū)ο?/h1>
語法糖??
在class
類的內(nèi)部 只能出現(xiàn)方法
class User{
//聲明屬性->魔術(shù)方法 當(dāng)User類被實例化時直接自動調(diào)用
constructor(userName,sex){//固定名字
this.userName = userName;
this.sex = sex惫霸;
this.doing();//實例化下面的doing方法
}
//聲明方法
doing(){
console.log('...xxx...');
}
}
var obj = new User('么么噠'猫缭,'男');
//調(diào)用方法
obj.doing();//...xxx...
//調(diào)用屬性
obj.userName;//么么噠
obj.sex;//男
ES6繼承
父
class Phone{
constructor(color,type){
this.color = color;
this.type = type;
}
callNum(){
console.log("i can call....")
}
}
子
class Hw extends Phone{ //通過extends關(guān)鍵字繼承
constructor(size,color,type){
super(color,type);//必須使用super關(guān)鍵字子級和父級的繼承關(guān)系才正常 這樣就會把兩級的構(gòu)造函數(shù)合并
this.size = size;
}
hwx(){
console.log("i can position...");
}
}
var obj = new Hw("p30",'red','iphone');
obj.callNum();//i can call....
obj.type;//iphone
obj.color;//red
當(dāng)子函數(shù)沒有構(gòu)造函數(shù)的時候會驅(qū)動父級的構(gòu)造函數(shù),
es6
繼承時需要使用super()
方法關(guān)聯(lián) 參數(shù)位置寫父構(gòu)造函數(shù)的參數(shù)。
類的特征
!!!
<font color=red size=4>1.封裝 2.繼承 3.多態(tài)</font>
!!!
PHP構(gòu)造函數(shù)
class Person{
public $color = 'red';
//構(gòu)造函數(shù)
function__construct(){
}
function doing(){
}
}