一锋八、JavaScript基礎(chǔ)知識回顧
1.1 JavaScript
1.1.1 javascript是什么鳄逾?
JavaScript是一門編程語言蝎抽,用來操作頁面標簽和樣式。
1.1.2 javascript的組成
-
ECMAScript:可以為不同種類的宿主環(huán)境提供核心的腳本編程能力缚去,因此核心的腳本語言是與任何特定的宿
主環(huán)境分開進行規(guī)定的潮秘。Web 瀏覽器對于 ECMAScript 來說是一個宿主環(huán)境,但它并不是唯一的宿主環(huán)境易结。
ECMAScript描述了以下內(nèi)容:語法枕荞、類型搞动、語句躏精、關(guān)鍵字、保留字鹦肿、運算符矗烛、對象。 -
DOM:(Document Object Model 文檔對象模型)是 HTML 和 XML 的應用程序接口(API)箩溃。DOM 將把
整個頁面規(guī)劃成由節(jié)點層級構(gòu)成的文檔瞭吃。HTML 或 XML 頁面的每個部分都是一個節(jié)點的衍生物。用 DOM
API 可以輕松地刪除涣旨、添加和替換節(jié)點歪架。 - BOM:(Browser Object Model 瀏覽器對象模型)可以對瀏覽器窗口進行訪問和操作。
1.1.3 ECMAScript與JavaScript的關(guān)系
前者是后者的規(guī)格霹陡,后者是前者的一種實現(xiàn)和蚪。
1.1.4 JavaScript中的數(shù)據(jù)類型
- 基本類型:number string boolean null undefined
- 引用類型:object (Array Date Math(比較特別) RegExp Function Object Error Number String Boolean XMLHttpRequest )
- 基本類型與引用類型的差別:
- 存儲方式不同:基本類型數(shù)據(jù)存儲在棧stack;引用類型存儲在堆heap穆律。
- 賦值方式不同:基本類型賦值的時候傳遞的是具體的值惠呼;引用類型賦值的時候傳遞的是內(nèi)存的地址。
1.1.5 JavaScript中的語句
- 分支:if,if else,switch
- 循環(huán):do while,while,for,for in
1.2 異常處理
作用:
- 防止某些程序出錯時影響后面代碼的執(zhí)行峦耘。
- 屏蔽底層的報錯細節(jié),從而給用戶一個友好提示旅薄。
var abc = 123;
try{
var data = false;
if(!false){
throw new Error('數(shù)據(jù)格式異常');
}
//try當中的代碼一旦發(fā)生錯誤辅髓,try當中之后的代碼就不再執(zhí)行了
console.log(abc);
}catch(e){
//只有try當中的代碼發(fā)生錯誤泣崩,這里才會執(zhí)行
console.log(e.message);//表示錯誤原因
console.log(e.name);//表示錯誤類型
}finally{
//無論try當中的代碼是否執(zhí)行,這里都會執(zhí)行
console.log(abc);
}
二洛口、面向?qū)ο?/h2>
2.1 面向?qū)ο蟾攀?/h3>
2.1.1 什么是對象
所謂的對象就是某種事物矫付,萬物皆對象。
用程序的方式描述對象:屬性+行為第焰。
2.1.2 對象創(chuàng)建方式
-
字面量:各種數(shù)據(jù)類型的字面量表示买优。
var obj1 = {
username : '張三',
age : 12,
gender : 'male'
};
-
構(gòu)造函數(shù):內(nèi)置對象和自定義對象。
var obj2 = new Object();
obj2.username = '李四';
obj2.age = 13;
obj2.gender = 'female';
如果構(gòu)造函數(shù)不需要傳遞參數(shù)挺举,那么后面的括號可以省略杀赢。
var obj = new Object();
var obj = new Object;
2.1.3 屬性的訪問方式
-
對象名.屬性名稱
。
-
對象名['屬性名稱']
湘纵。
2.1.1 什么是對象
所謂的對象就是某種事物矫付,萬物皆對象。
用程序的方式描述對象:屬性+行為第焰。
2.1.2 對象創(chuàng)建方式
-
字面量:各種數(shù)據(jù)類型的字面量表示买优。
var obj1 = { username : '張三', age : 12, gender : 'male' };
-
構(gòu)造函數(shù):內(nèi)置對象和自定義對象。
var obj2 = new Object(); obj2.username = '李四'; obj2.age = 13; obj2.gender = 'female';
如果構(gòu)造函數(shù)不需要傳遞參數(shù)挺举,那么后面的括號可以省略杀赢。
var obj = new Object(); var obj = new Object;
2.1.3 屬性的訪問方式
-
對象名.屬性名稱
。 -
對象名['屬性名稱']
湘纵。
兩種方式的區(qū)別:方括號的方式可以使用變量脂崔。
2.1.4 實例化的本質(zhì)
構(gòu)造函數(shù)實例化對象本質(zhì)上做了什么工作?
- 開辟堆內(nèi)存用來存儲實例中數(shù)據(jù)(屬性和方法)梧喷。
- 用this指向該區(qū)域砌左。
- 通過this向該區(qū)域中放置數(shù)據(jù)。
- 返回this
function Foo(info){
// 構(gòu)造函數(shù)中的this指的是構(gòu)造函數(shù)所創(chuàng)建的實例對象
this.info = info;
this.showInfo = function(){
// 實例方法中的this指向方法的調(diào)用者(實例對象本身)
console.log(this.info);
}
// 構(gòu)造函數(shù)的默認返回值就是this
}
var foo = new Foo('tom');
foo.showInfo();
var foo1 = new Foo('jerry');
foo1.showInfo();
2.1.5 構(gòu)造函數(shù)的返回值
- 構(gòu)造函數(shù)如果顯示的返回基本數(shù)據(jù)類型铺敌,那么和不返回等效汇歹。
- 構(gòu)造函數(shù)如果顯示的返回引用數(shù)據(jù)類型,那么就以此為準偿凭,就不再返回默認的this了秤朗。
function Person(name){
this.name = name;
return 123; //輸出:Person {name: "zhangsan"}
return 'hello'; //輸出:Person {name: "zhangsan"}
return {
name : 'lisi',
age : 12
}; //輸出:Object {name: "lisi", age: 12}
return [1,2,3]; //輸出:[1,2,3]
}
var p = new Person('zhangsan');
console.log(p);
2.1.6 對象原型
JavaScript中對象的本質(zhì):無序的鍵值對集合。
原型:實現(xiàn)數(shù)據(jù)共享(實例對象之間進行數(shù)據(jù)共享)笔喉。
function Foo(info){
this.info = info;
this.showInfo = function(){
console.log(this.info);
}
}
var f1 = new Foo('tom');
var f2 = new Foo('jerry');
console.log(f1.showInfo === f2.showInfo);//false
-------------------------------------------------------------------------------
function fn(){
console.log(this.name);
}
function Person(name,age){
this.name = name;
this.age = age;
this.showName = fn;
}
var p1 = new Person('zhangsan');
var p2 = new Person('lisi');
console.log(p1.showName === p2.showName);//true
2.1.7 原型分析
原型:函數(shù)都有一個原型屬性prototype取视,該屬性值本質(zhì)上也是對象(實際就是Object的實例)。
原型的作用:實現(xiàn)數(shù)據(jù)共享(實例對象之間進行共享)常挚;實現(xiàn)繼承作谭。
__proto__
:構(gòu)造函數(shù)產(chǎn)生的實例對象都有一個屬性__proto__
,該屬性不是標準屬性奄毡,不可以在編程中使用折欠,實際上該屬性是瀏覽器內(nèi)部使用的,該屬性和構(gòu)造函數(shù)中的prototype指向相同吼过。
__proto__
屬性在實例對象中锐秦,prototype屬性在構(gòu)造函數(shù)中,這兩個屬性的指向是相同的盗忱。
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.showName = function(){
console.log(this.name);
}
Person.prototype.showAge = function(){
console.log(this.age);
}
Person.prototype.flag = 123;
Person.prototype.arr = ['red','green','blue'];
var p1 = new Person('tom',12);
p1.flag = 456;
p1.arr.push('pink');
var p2 = new Person('jerry',13);
console.log(p1.flag,p2.flag); //456 123
console.log(p1.arr,p2.arr); //["red", "green", "blue", "pink"] ["red", "green", "blue", "pink"]
//解釋:
//通過對象.屬性名稱=值 這種做法會向?qū)ο笾刑砑右粋€屬性
//但是obj.arr.push(123); 這種結(jié)構(gòu)不會再obj中添加屬性酱床,而會obj.arr數(shù)組中添加一項數(shù)據(jù)
2.2 面向過程與面向?qū)ο?/h3>
2.2.1 相關(guān)概念
-
面向?qū)ο笫且环N編程模式,就是以對象的方式寫代碼趟佃。
三大特性:封裝扇谣、繼承那個昧捷、多態(tài)。
面向過程的編程模式的缺點:團隊開發(fā)容易產(chǎn)生命名沖突罐寨;不方便代碼的重用靡挥;可維護性差。
-
JavaScript面向?qū)ο笙嚓P(guān)概念:
- 構(gòu)造函數(shù)
- 實例對象
- 原型
2.2.2 面向?qū)ο箝_發(fā)
//實現(xiàn)如下功能:點擊一個按鈕改變div的背景色
//用面向?qū)ο蟮娘L格封裝(構(gòu)造函數(shù)+原型)
function ChangeColor(btnId,divId){
this.btn = document.getElementById(btnId);
this.div = document.getElementById(divId);
}
ChangeColor.prototype.init = function(){
// 原型方法中的this指的是該原型所屬的構(gòu)造函數(shù)的實例化對象鸯绿,實際上與構(gòu)造函數(shù)中的this指向相同
var that = this;//緩存實例對象
this.btn.onclick = function(){
// 這里的this是綁定事件函數(shù)的DOM對象
that.div.style.backgroundColor = 'yellow';
}
}
onload = function(){
var cc = new ChangeColor('btn','div1');
cc.init();
}
//不同的this場景:
//1跋破、構(gòu)造函數(shù)中的this
//2、原型方法中的this
//3瓶蝴、事件方法中的this
//1) 構(gòu)造函數(shù)中的this和原型方法中的this指向相同:都是指向?qū)嵗龑ο?//2)事件方法中的this指的是綁定事件的對象
2.2.3 對象中屬性的判斷
-
in:判斷對象中是否存在某個屬性(屬性在實例對象和原型對象都可以)毒返。
-
hasOwnProperty():判斷屬性是否在實例對象上。
//小測試:
if('a' in window) {
var a = 123
console.log(a);
}
//輸出:123
//考點:
//1.全局作用域中的變量和函數(shù)都是window對象的成員
//2.預解析
//3.js中沒有塊級作用域
//實現(xiàn)一份方法囊蓝,判斷某個屬性是否在原型上
function check(attr,obj){
if(attr in obj && !obj.hasOwnProperty(attr)){
return true;
}else{
return false;
}
}
2.3 構(gòu)造函數(shù)退渗、原型與實例的關(guān)系
2.3.1 構(gòu)造函數(shù)诫睬、原型與實例的關(guān)系
- 構(gòu)造函數(shù)中都有原型屬性prototype狸膏,該屬性值本質(zhì)也是對象(Object的實例對象)
- 原型對象中都有一個屬性constructor微宝,該屬性指向原型所屬的構(gòu)造函數(shù)
- 實例對象中都有一個屬性
__proto__
,該屬性不是標準屬性蝎宇,不可以在編程中使用弟劲,實際上是瀏覽器內(nèi)部使用的,并且該屬性指向原型對象姥芥。
2.3.2 原型鏈
原型鏈:實例對象和原型對象之間形成的有限鏈式結(jié)構(gòu)兔乞,該鏈式結(jié)構(gòu)通過__proto__
連接起來,用于實現(xiàn)繼承和共享屬性凉唐。
-
對象是有原型對象的庸追,原型對象也有原型對象,原型對象也有原型對象台囱,對象的原型對象一直往上找淡溯,會找到一個null。
var obj = new Object();
// obj -> Object.prototype -> null
var arr = new Array();
// arr -> Array.prototype -> Object.prototype -> null
var date = new Date();
// date -> Date.prototype -> Object.prototype -> null
-
原型鏈的結(jié)構(gòu)可以通過重置原型對象的方式來修改簿训。
function Foo1(info){
this.info = info;
}
Foo2.prototype = new Foo1('tom');
//Foo2.prototype.constructor = Foo1;
function Foo2(info){
this.info = info;
}
Foo3.prototype = new Foo2('jerry');
//Foo3.prototype.constructor = Foo2;
function Foo3(info){
this.info = info;
}
var f = new Foo3('spike');
console.dir(f);
// f -> new Foo2('jerry') -> new Foo1('tom') -> Foo1.prototype -> Object.prototype -> null
2.4 繼承
繼承:別人的拿過來咱娶,自己的還是自己的∏科罚可以通過修改原型的指向來實現(xiàn)膘侮。
2.4.1 原型繼承
function Animal() {
this.name = '動物';
}
function Tiger(color) {
this.color = color;
}
Tiger.prototype = new Animal();
var tiger = new Tiger('黃色');
console.log(tiger.name);
console.log(tiger.color);
面向?qū)ο笫且环N編程模式,就是以對象的方式寫代碼趟佃。
三大特性:封裝扇谣、繼承那個昧捷、多態(tài)。
面向過程的編程模式的缺點:團隊開發(fā)容易產(chǎn)生命名沖突罐寨;不方便代碼的重用靡挥;可維護性差。
JavaScript面向?qū)ο笙嚓P(guān)概念:
- 構(gòu)造函數(shù)
- 實例對象
- 原型
//實現(xiàn)如下功能:點擊一個按鈕改變div的背景色
//用面向?qū)ο蟮娘L格封裝(構(gòu)造函數(shù)+原型)
function ChangeColor(btnId,divId){
this.btn = document.getElementById(btnId);
this.div = document.getElementById(divId);
}
ChangeColor.prototype.init = function(){
// 原型方法中的this指的是該原型所屬的構(gòu)造函數(shù)的實例化對象鸯绿,實際上與構(gòu)造函數(shù)中的this指向相同
var that = this;//緩存實例對象
this.btn.onclick = function(){
// 這里的this是綁定事件函數(shù)的DOM對象
that.div.style.backgroundColor = 'yellow';
}
}
onload = function(){
var cc = new ChangeColor('btn','div1');
cc.init();
}
//不同的this場景:
//1跋破、構(gòu)造函數(shù)中的this
//2、原型方法中的this
//3瓶蝴、事件方法中的this
//1) 構(gòu)造函數(shù)中的this和原型方法中的this指向相同:都是指向?qū)嵗龑ο?//2)事件方法中的this指的是綁定事件的對象
//小測試:
if('a' in window) {
var a = 123
console.log(a);
}
//輸出:123
//考點:
//1.全局作用域中的變量和函數(shù)都是window對象的成員
//2.預解析
//3.js中沒有塊級作用域
//實現(xiàn)一份方法囊蓝,判斷某個屬性是否在原型上
function check(attr,obj){
if(attr in obj && !obj.hasOwnProperty(attr)){
return true;
}else{
return false;
}
}
__proto__
,該屬性不是標準屬性蝎宇,不可以在編程中使用弟劲,實際上是瀏覽器內(nèi)部使用的,并且該屬性指向原型對象姥芥。原型鏈:實例對象和原型對象之間形成的有限鏈式結(jié)構(gòu)兔乞,該鏈式結(jié)構(gòu)通過__proto__
連接起來,用于實現(xiàn)繼承和共享屬性凉唐。
對象是有原型對象的庸追,原型對象也有原型對象,原型對象也有原型對象台囱,對象的原型對象一直往上找淡溯,會找到一個null。
var obj = new Object();
// obj -> Object.prototype -> null
var arr = new Array();
// arr -> Array.prototype -> Object.prototype -> null
var date = new Date();
// date -> Date.prototype -> Object.prototype -> null
原型鏈的結(jié)構(gòu)可以通過重置原型對象的方式來修改簿训。
function Foo1(info){
this.info = info;
}
Foo2.prototype = new Foo1('tom');
//Foo2.prototype.constructor = Foo1;
function Foo2(info){
this.info = info;
}
Foo3.prototype = new Foo2('jerry');
//Foo3.prototype.constructor = Foo2;
function Foo3(info){
this.info = info;
}
var f = new Foo3('spike');
console.dir(f);
// f -> new Foo2('jerry') -> new Foo1('tom') -> Foo1.prototype -> Object.prototype -> null
繼承:別人的拿過來咱娶,自己的還是自己的∏科罚可以通過修改原型的指向來實現(xiàn)膘侮。
function Animal() {
this.name = '動物';
}
function Tiger(color) {
this.color = color;
}
Tiger.prototype = new Animal();
var tiger = new Tiger('黃色');
console.log(tiger.name);
console.log(tiger.color);
缺點:沒有辦法給基礎(chǔ)過來的屬性賦值,而不影響所有的實例的榛。繼承過來的引用類型的數(shù)據(jù)琼了,所有的實例時共享的。
2.4.2 借用構(gòu)造函數(shù)繼承
-
call和apply的基本使用:
- call和apply可以調(diào)用函數(shù)困曙。
- 改變所調(diào)用函數(shù)內(nèi)部的this指向表伦。
- 在非嚴格模式下谦去,普通函數(shù)中this是window慷丽;在嚴格模式下蹦哼,普通函數(shù)中this是undefined。
-
借用構(gòu)造函數(shù)繼承:
function Person(name,favour){ this.name = name; this.favour = favour; } Person.prototype.showName = function(){ console.log(this.name); } function Student(num,name,favour){ // 這里的this是Student構(gòu)造函數(shù)的實例 // Person.call(this,name,favour); Person.apply(this,[name,favour]); this.num = num; } var stu1 = new Student(1,'zhangsan',['coding']); stu1.favour.push('swimming'); var stu2 = new Student(2,'lisi',['dancing']); console.dir(stu1); console.dir(stu2); stu1.showName();
缺點:沒有辦法繼承父級構(gòu)造函數(shù)原型上的成員要糊。
2.4.3 組合繼承
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.show=function(){
console.log(this.name+"今年"+this.age+"歲了");
}
Person.prototype.flag=1;
function Teacher(name,age,level){
Person.call(this,name,age);
this.level=level;
}
Teacher.prototype=new Person();
var t1 = new Teacher("張三",33,"T5");
var t2 = new Teacher("李四",30,"T4");
t1.show();
2.5 Object.create的基本使用
//ES5新特性纲熏,方法的作用:創(chuàng)建對象
var create = function(obj){
if(Object.create){
return Object.create(obj);
}else{
function F(){}
F.prototype = obj;
return new F();
}
}
2.6 屬性的復制
2.6.1 淺拷貝
var obj = {};
var obj1 = {
username : 'zhangsan',
age : 12,
gender : 'male'
}
function extend(des,origin){
for(var key in origin){
des[key] = origin[key];
}
}
extend(obj,obj1);
console.log(obj);
2.6.2 深拷貝
function foo(set){
var defaultSettings = {
width : '100',
height : '200',
backgroundColor : 'gray',
sets : {
flag : 12,
abc : 'message'
}
}
var obj = {
www : 'www'
}
var obj1 = {
qqq : 'qqq'
}
$.extend(true,defaultSettings,set,obj,obj1);
console.dir(defaultSettings);
console.log(defaultSettings.width);
console.log(defaultSettings.sets.flag);
console.log(defaultSettings.sets.abc);
}
var settings = {
width : '1000',
sets : {
flag : 123,
}
}
foo(settings);
2.7 函數(shù)
2.7.1 函數(shù)的原型鏈
-
Function:
- 所有的函數(shù)都是Function的實例。
- Funciton也是一個函數(shù)锄俄。
2.7.2 函數(shù)的三種角色
- 構(gòu)造函數(shù)
- 普通函數(shù)
- 函數(shù)作為對象
function Foo(){}
var foo = new Foo(); //構(gòu)造函數(shù)
Foo(); //普通函數(shù)
Foo.info = 'hello'; //函數(shù)作為對象
函數(shù)到底是哪種角色局劲,取決于函數(shù)的調(diào)用方式
2.7.3 函數(shù)的定義方式
系統(tǒng)函數(shù)(類庫、庫函數(shù))
-
自定義函數(shù)
-
函數(shù)聲明
function foo(){ console.log(123); }
-
函數(shù)表達式
var fn = function(){ console.log(456); } fn();
-
new Function()
var fn1 = new Function('console.log(789);');//需要把字符串轉(zhuǎn)成js代碼并執(zhí)行奶赠,性能沒有前兩者好 fn1();
區(qū)別:
- 函數(shù)聲明是在預解析階段創(chuàng)建的鱼填,而函數(shù)表達式是在程序執(zhí)行階段創(chuàng)建的。
- 函數(shù)聲明只能在全局或者函數(shù)內(nèi)部定義毅戈,而函數(shù)表達式只能在表達式中定義苹丸。
-
函數(shù)都是對象,但對象不一定是函數(shù)苇经。
Math不是函數(shù)赘理,而是對象
2.7.4 this的不同指向場景
-
函數(shù)的調(diào)用方式:(函數(shù)中的this指向取決與函數(shù)的調(diào)用方式)
- 構(gòu)造函數(shù)
- 普通函數(shù)
- 對象方法
- call和apply調(diào)用(bind)
-
this的不同指向:
- 構(gòu)造函數(shù)中的this指向?qū)嵗龑ο?/li>
- 原型方法中的this指向?qū)嵗龑ο螅c構(gòu)造函數(shù)中的this指向相同
- 在非嚴格模式下扇单,普通函數(shù)中的this指向window商模,在嚴格模式下,普通函數(shù)中的this指向undefined
- 對象方法中的this就是調(diào)用方法的對象
- 事件方法中的this指的是綁定事件的對象
- 定時函數(shù)中的this指的是window
- call或apply所調(diào)用的函數(shù)中的this就是call或apply中的第一個參數(shù)(該參數(shù)必須是引用類型)
-
bind的基本用法:
- bind方法是ES5的新特性(函數(shù)的柯里化)
- bind用來改變函數(shù)內(nèi)部的this指向蜘澜,但是不調(diào)用函數(shù)施流,并且bind會返回一個新函數(shù)(其實還是原來的函數(shù)內(nèi)容,只是this改變?yōu)閎ind中的第一個參數(shù)鄙信,該參數(shù)必須為引用類型)
var inner = function(a,b){ console.log(a+b); } var newInner = inner.bind({info:'hello'},12,13); setTimeout(newInner,1000);
2.7.5 高階函數(shù)
高階函數(shù):
-
作為參數(shù)的函數(shù)
function foo(fn) { var data = { info: 'hello' } fn(data); } var fn = function(data) { console.log(data.info); }; foo(fn);
-
作為返回值的函數(shù)(閉包)
function foo(){ var num = 1; return function(){ return num++; } } var fn = foo(); var r1 = fn(); var r2 = fn(); console.log(r1,r2);
2.8 對象加深
2.8.1 對象的體系結(jié)構(gòu)
- 所有的實例對象都有一個
__proto__
屬性瞪醋,該屬性指向產(chǎn)生實例對象的構(gòu)造函數(shù)的原型。 - 所有的構(gòu)造函數(shù)都有一個prototype屬性扮碧,該屬性本質(zhì)上也是一個對象(Object的實例對象)
- 所有的原型對象都有一個constructor屬性趟章,該屬性指向原型所屬的構(gòu)造函數(shù)。
- 原型對象中有一個
__proto__
屬性慎王,該屬性指向Object.prototype(Object的原型對象中沒有__proto__
蚓土,因為這里就是原型鏈的終點) - 所有的函數(shù)都是Function的實例對象。
- Function函數(shù)本身也是它自己的實例對象(也就是
Function.__proto__
===Function.prototype)
2.8.2 基本類型與引用類型深入理解
-
基本類型
var num = 123 function foo(data){ data = '456'; return data; } var ret = foo(num); console.log(ret,num);//456 123
-
引用類型
var arr = [1,2,3]; function foo(data){ data.push(4); return data; } var ret = foo(arr); console.log(ret,arr);//[1, 2, 3, 4] [1, 2, 3, 4]
2.8.3 標準庫
- 常用對象:Object赖淤、Array蜀漆、Date、RegExp咱旱、Math确丢、Function绷耍、Error
- 包裝對象:Number、String鲜侥、Boolean
2.8.4 類數(shù)組(關(guān)聯(lián)數(shù)組)詳解
-
類數(shù)組:
var obj = { 0 : 'qqq', 1 : 'www', 2 : 'eee', length : 3 }
-
類數(shù)組轉(zhuǎn)數(shù)組:
var arr = [].slice.call(obj,0);
-
delete的用法:
var obj = { info : 'abc', username : 'lisi' } delete obj.info; console.log(obj);//Object {username: "lisi"} var flag = 123; delete flag; console.log(flag);//123
- delete的作用就是刪除對象的屬性褂始。
- 全局作用域中var聲明的變量,delete無法刪除描函,但是不用var聲明的全局變量可以delete刪除崎苗。
-
求數(shù)組中的最大值:
//排序 var arr = [12321,234,99999999,4454,12,454545,343,34,342]; arr.sort(function(a,b){ return b - a; }); console.log(arr);//[99999999, 454545, 12321, 4454, 343, 342, 234, 34, 12] //對象中的Math方法 var max = Math.max(123,23,4324,45,4,645,6,45645); console.log(max); //借用對象的方法 var max = Math.max.apply(null,arr); console.log(max);
call和apply的應用場景:
- 調(diào)用函數(shù)
- 改變所調(diào)用函數(shù)的內(nèi)部this指向
- 轉(zhuǎn)換類數(shù)組
- 借用別的對象方法
2.9 遞歸
2.9.1 遞歸的執(zhí)行原理
function fn(n){
if(n == 1){
console.log('遞歸結(jié)束' + n);
return 1;
}else{
console.log('遞歸前' + n);
var ret = n * fn(n-1);
console.log('遞歸后' + n);
return ret;
}
}
var ret = fn(5);
console.log(ret);
/* 輸出結(jié)果:
遞歸前5
遞歸前4
遞歸前3
遞歸前2
遞歸結(jié)束1
遞歸后2
遞歸后3
遞歸后4
遞歸后5
120
*/
2.9.2 遞歸的應用
function getChildNodes(node, arr) {
for (var i = 0; i < node.childNodes.length; i++) {
var subNode = node.childNodes[i];
//如果子節(jié)點是元素類型就放到數(shù)組中
if (subNode.nodeType == 1) {
arr.push(subNode);
//以當前子節(jié)點作為新的父節(jié)點繼續(xù)遞歸
getChildNodes(subNode, arr);
}
}
}
window.onload = function () {
var arr = [];
var div = document.getElementById('div');
getChildNodes(div, arr);
console.log(arr);
}
2.9.3 jQuery實例化過程
$(function(){
// var ret = $('.active');
// console.dir(ret);
// ret.html('123').css('backgroundColor','green');
// var aDiv = document.getElementsByTagName('div')[0];
// console.dir(aDiv);
// // ret[0];
// console.log(ret.get(0) === aDiv);
function jQuery(selector){
return new jQuery.prototype.init(selector);
}
jQuery.prototype = {
constructor : jQuery,
html : function(){
console.log(123);
return this;
},
css : function(){
console.log(456);
return this;
},
init : function(selector){
// 實現(xiàn)選擇器功能
// div .active #div1 div span .active div span
// Sizzle
var aDiv = document.getElementsByTagName(selector);
// 把每一個div都放到this中,那么this就是一個類數(shù)組
[].push.apply(this,aDiv);
this.length = aDiv.length;
}
}
jQuery.prototype.init.prototype = jQuery.prototype;
var obj = jQuery('div');
obj.html('123').css(456);
// obj.html('hello').css();
$('div').css('width');//獲取某個樣式值
$('div').css('width','100px');//設(shè)置樣式值
$('div').css({
width : '100px',
height : '100px'
});
$('div').css(['width','height']);//{width : 100px,height : 100px}
});
//待整理
2.10 作用域與閉包
2.10.1 作用域
作用域:指的是變量的作用范圍舀寓。
- 全局作用域
- 函數(shù)作用域
- js沒有塊級作用域
作用域鏈:鏈是一個對象列表(list of objects) 胆数,用以檢索上下文代碼中出現(xiàn)的標識符(identifiers) 。標示符可以理解為變量名稱互墓、函數(shù)聲明和普通參數(shù)必尼。作用域鏈包括活動對象和父級變量對象。
- 函數(shù)內(nèi)層作用域可以訪問外層作用篡撵,但是反過來不可以判莉。
2.10.2 預解析
JavaScript解析器在執(zhí)行代碼的時候分為兩個階段:
- 預解析
- 全局預解析(所有的變量和函數(shù)聲明都會提前;同名的函數(shù)和變量函數(shù)的優(yōu)先級高)
- 函數(shù)內(nèi)部預解析(所有的變量酸休、函數(shù)和形參都會預解析骂租,優(yōu)先級:函數(shù) > 形參 > 變量)
- 從上到下逐行執(zhí)行
先預解析全局作用域,然后執(zhí)行全局作用域中的代碼斑司,在執(zhí)行全局代碼的過程中遇到函數(shù)調(diào)用就會先進行函數(shù)預解析渗饮,然后再執(zhí)行函數(shù)內(nèi)的代碼。
2.10.3 閉包
閉包是一系列代碼塊(在ECMAScript中是函數(shù))宿刮,并且靜態(tài)保存所有父級的作用域互站。通過這些保存的作用域來搜尋到函數(shù)中的自由變量。
當一個函數(shù)在自身函數(shù)體內(nèi)需要引用一個變量僵缺,但是這個變量并沒有在函數(shù)內(nèi)部聲明(或者也不是某個參數(shù)名)胡桃,那么這個變量就可以稱為自由變量[free variable]。
閉包:
- 封閉的區(qū)域
- 函數(shù)的嵌套形成閉包(內(nèi)層函數(shù)和內(nèi)層函數(shù)所處的作用域)
- 閉包可以操作函數(shù)內(nèi)部的變量(間接的)
閉包的作用:
- 可以緩存中間狀態(tài)值
- 延長變量的生命周期
var arr = [];
for (var i = 0; i < 3; i++) {
arr[i] = (function(num){
return function(){
console.log(num);
}
})(i);
}
arr[0](); //0
arr[1](); //1
arr[2](); //2
閉包的應用:
onload = function(){
var aInput = document.getElementsByTagName('input');
for (var i = 0; i < aInput.length; i++) {
// aInput[i].onclick = (function(){
// var num = 0;
// return function(){
// ++num;
// console.log(num);
// }
// })();
aInput[i].onclick = function(){
this.num?++this.num:this.num=1;
console.log(this.num);
console.dir(this);
}
}
}
2.10.4 對象排序
function sortFn(sortName){
return function(a,b){
var v1 = a[sortName];
var v2 = b[sortName];
if(v1 > v2){
return 1;
}else if(v1 < v2){
return -1;
}else{
return 0;
}
}
}
2.11 事件
2.11.1 函數(shù)相關(guān)屬性補充
- arguments 表示實參的集合
- length 形參的個數(shù)
- caller 函數(shù)的調(diào)用者
- name 函數(shù)的名稱
- arguments.callee 表示函數(shù)本身磕潮,但是不推薦使用
2.11.2 事件處理機制
- 瀏覽器本身是單線程還是多線程翠胰?多線程(多進程)
- 頁面標簽的渲染
- 網(wǎng)絡(luò)通信
- 解析js的運行
- js的運行是單線程的
- 事件隊列(隊列中放什么?任務(wù)(實際上就是函數(shù)))
- 定時函數(shù)(延時時間到了)
- 事件函數(shù)(對應的事件觸發(fā))
- Ajax的回調(diào)函數(shù)(接收到服務(wù)器完整的數(shù)據(jù)(readyState值發(fā)生變化的時候))
- 事件隊列中任務(wù)執(zhí)行的條件:
- 主線程空閑
- 滿足任務(wù)的觸發(fā)條件
2.11.3 事件綁定方式
-
行內(nèi)綁定
<div onclick="fn3();"> <div onclick="fn2();"> <div onclick="fn1();">點擊</div> </div> </div>
-
給DOM元素直接綁定 btn.onclick
div.onclick = function(){ console.log(1); }
-
addEventListener / attachEvent
div.addEventListener('click',function(){ console.log(11); },false)
2.11.4 阻止冒泡與阻止默認行為
- 在原生js中自脯,return false只能阻止默認行為之景,不能阻止冒泡;只能阻止btn.onclick這種方式綁定的事件膏潮,不能阻止addEventListener綁定的事件锻狗。
- 在jQuery中,return false既可以阻止冒泡也可以阻止默認行為。
2.11.5 自定義事件
-
注冊事件
function addEvent(obj,type,fn){ obj.arrs = obj.arrs || {}; obj.arrs[type] = obj.arrs[type] || []; obj.arrs[type].push(fn); } var obj = {}; addEvent(obj,'abc',function(){ console.log('abc'); }); addEvent(obj,'abc',function(){ console.log('abc1'); }); addEvent(obj,'hi',function(){ console.log('hi'); });
-
觸發(fā)事件
function fireEvent(obj,type){ var fnList = obj.arrs[type]; for (var i = 0; i < fnList.length; i++) { fnList[i](); } } fireEvent(obj,'hi');
2.12 正則
2.12.1 正則相關(guān)API
-
正則的API:
-
test
var reg = /\d/; console.log(reg.test('123'));
-
exec
var str = 'adsfasdf123asdfasdf21312sfdsadfad'; var reg = /\d+/g; // var ret = reg.exec(str); // console.log(ret); var result = null; while((result = reg.exec(str)) != null) { console.log("Matched `" + result[0] + "' at position " + result.index + " next search begins at position " + reg.lastIndex); }
-
-
字符串API:
-
search:查詢匹配字符串的索引
var str = 'dsdaf123asdfasdf'; console.log(str.search('123')); console.log(str.search(/\d+/));
-
match
//從字符串中找出數(shù)字 var str = '1212adsfasdf123asdfasd234fqewrqew3434rqwerw54qerqwerqwer21321'; console.log(str.match(/\d+/g));
-
split
var str = 'zhangsan:12:male;lisi:13:female'; var arr = str.split(';'); for (var i = 0; i < arr.length; i++) { var item = arr[i].split(':'); console.log(item[0]); console.log(item[1]); console.log(item[2]); } var str = 'asdfasdfasdf123asdfas4545dfads'; var arr = str.split(/\d+/g); console.log(arr);
-
replace
var str = 'adsfasdf123asdfasdf21312sfdsadfad'; str = str.replace(/\d+/g,'***'); console.log(str);
-
在非全局匹配模式下轻纪,
str.match(reg)
和reg.exec(str)
的作用等效油额。
2.12.2 正則的規(guī)則
- 元字符:
三、面試題
3.1 ==和===相關(guān)的比較問題
[] ==![] //true
[1] == [1] //false
[1] == ![1] //false
比較規(guī)則:
- 對象之間的比較是內(nèi)存地址的比較
- 單個空對象轉(zhuǎn)成布爾值是true
- 空數(shù)組與布爾值的比較會轉(zhuǎn)換成數(shù)值的比較(空數(shù)組會轉(zhuǎn)化成0)
- 轉(zhuǎn)成false的情況:
false null '' undefined 0 NaN
3.2 in使用中的問題
3.2.1 變量聲明時的問題
console.log('a' in window); //true
if('a' in window){
var a = 123;
console.log(a);
}
console.log('a' in window); //false
if('a' in window){
a = 123;
console.log(a);
}
- 不使用var不會預解析刻帚,但是也會向window中添加屬性潦嘶。
3.2.2 window中的undefined
console.log(a in window); //true
if(a in window){
var a = 123;
console.log(a);
}
- 不加引號,a是undefined我擂,window中本身就有一個屬性undefined衬以,并且undefined的值也是undefined缓艳。
3.3 以下代碼的輸出結(jié)果是什么校摩?
var a = {n:1};
var b = a;
a.x = a = {n:2}; //運算符的優(yōu)先級 .的優(yōu)先級最高 賦值操作是從右向左運算的
console.log(a.x); //undefined
console.log(b.x); //{n:2}
考點:
- 基本類型和引用類型
- 引用類型變量和對象屬性(在內(nèi)存實際上就是內(nèi)存地址)
- 運算符的優(yōu)先級
.
的優(yōu)先級最高 ,賦值操作是從右向左運算的
3.4 下列代碼輸出結(jié)果是什么阶淘?
var a = {name:'zhangsan'};
var b = {age : 26};
var arr = [];
arr[a] = 123;
arr[b] = 456;
console.log(arr);//Array[0] -->[object Object]:456
數(shù)組也是對象
對象屬性的訪問方式
Object的toString方法作用:把構(gòu)造函數(shù)轉(zhuǎn)成這種形式的字符串:[object Object]
3.5 跨域解決方案有哪些衙吩?
- jsonp
- cors
- 反向代理
- flash插件
3.6 DNS解析過程是什么?
- DNS Domain Name System : 負責域名和IP地址的映射關(guān)系
- 域名解析的規(guī)則:先去本機的hosts文件中查找IP溪窒,如果沒有找到坤塞,就去公網(wǎng)的DNS服務(wù)器查找,如果還沒有找到澈蚌,那就無法上網(wǎng)摹芙;如果在hosts文件中找到了,那么就返回ip,就不再去公網(wǎng)查找了
3.7 前端有多少種方式可以發(fā)送請求宛瞄?
1)瀏覽器地址直接輸入url
2)表單的action屬性
3)a標簽href屬性
4)img的src屬性
5)script的src屬性
6)link標簽的href屬性
7)iframe的src屬性
8)Ajax發(fā)送請求
9)postMessage h5新的API
10)flash插件也可以
11)location.href
url的規(guī)范格式:
scheme://host:port/path?query#fragment
echeme 表示協(xié)議 http https ftp file ssh
host 表示域名或者IP地址
port 端口 用來確定計算機上的具體某個網(wǎng)絡(luò)應用程序
path 域名之后浮禾,?之前的內(nèi)容 /abc/qqq/rrr
query 查詢字符串份汗,作用是向服務(wù)器傳遞數(shù)據(jù)盈电,格式:鍵=值&鍵=值
fragment hash 錨點 定位頁面的某一部分