一、JavaScript基礎知識回顧
1.1 JavaScript
1.1.1 javascript是什么?
JavaScript是一門編程語言,用來操作頁面標簽和樣式。
1.1.2 javascript的組成
-
ECMAScript:可以為不同種類的宿主環境提供核心的腳本編程能力,因此核心的腳本語言是與任何特定的宿
主環境分開進行規定的。Web 瀏覽器對于 ECMAScript 來說是一個宿主環境,但它并不是唯一的宿主環境。
ECMAScript描述了以下內容:語法、類型、語句、關鍵字、保留字、運算符、對象。 -
DOM:(Document Object Model 文檔對象模型)是 HTML 和 XML 的應用程序接口(API)。DOM 將把
整個頁面規劃成由節點層級構成的文檔。HTML 或 XML 頁面的每個部分都是一個節點的衍生物。用 DOM
API 可以輕松地刪除、添加和替換節點。 - BOM:(Browser Object Model 瀏覽器對象模型)可以對瀏覽器窗口進行訪問和操作。
1.1.3 ECMAScript與JavaScript的關系
前者是后者的規格,后者是前者的一種實現。
1.1.4 JavaScript中的數據類型
- 基本類型:number string boolean null undefined
- 引用類型:object (Array Date Math(比較特別) RegExp Function Object Error Number String Boolean XMLHttpRequest )
- 基本類型與引用類型的差別:
- 存儲方式不同:基本類型數據存儲在棧stack;引用類型存儲在堆heap。
- 賦值方式不同:基本類型賦值的時候傳遞的是具體的值;引用類型賦值的時候傳遞的是內存的地址。
1.1.5 JavaScript中的語句
- 分支:if,if else,switch
- 循環:do while,while,for,for in
1.2 異常處理
作用:
- 防止某些程序出錯時影響后面代碼的執行。
- 屏蔽底層的報錯細節,從而給用戶一個友好提示。
var abc = 123;
try{
var data = false;
if(!false){
throw new Error('數據格式異常');
}
//try當中的代碼一旦發生錯誤,try當中之后的代碼就不再執行了
console.log(abc);
}catch(e){
//只有try當中的代碼發生錯誤,這里才會執行
console.log(e.message);//表示錯誤原因
console.log(e.name);//表示錯誤類型
}finally{
//無論try當中的代碼是否執行,這里都會執行
console.log(abc);
}
二、面向對象
2.1 面向對象概述
2.1.1 什么是對象
所謂的對象就是某種事物,萬物皆對象。
用程序的方式描述對象:屬性+行為。
2.1.2 對象創建方式
-
字面量:各種數據類型的字面量表示。
var obj1 = { username : '張三', age : 12, gender : 'male' };
-
構造函數:內置對象和自定義對象。
var obj2 = new Object(); obj2.username = '李四'; obj2.age = 13; obj2.gender = 'female';
如果構造函數不需要傳遞參數,那么后面的括號可以省略。
var obj = new Object(); var obj = new Object;
2.1.3 屬性的訪問方式
-
對象名.屬性名稱
。 -
對象名['屬性名稱']
。
兩種方式的區別:方括號的方式可以使用變量。
2.1.4 實例化的本質
構造函數實例化對象本質上做了什么工作?
- 開辟堆內存用來存儲實例中數據(屬性和方法)。
- 用this指向該區域。
- 通過this向該區域中放置數據。
- 返回this
function Foo(info){
// 構造函數中的this指的是構造函數所創建的實例對象
this.info = info;
this.showInfo = function(){
// 實例方法中的this指向方法的調用者(實例對象本身)
console.log(this.info);
}
// 構造函數的默認返回值就是this
}
var foo = new Foo('tom');
foo.showInfo();
var foo1 = new Foo('jerry');
foo1.showInfo();
2.1.5 構造函數的返回值
- 構造函數如果顯示的返回基本數據類型,那么和不返回等效。
- 構造函數如果顯示的返回引用數據類型,那么就以此為準,就不再返回默認的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中對象的本質:無序的鍵值對集合。
原型:實現數據共享(實例對象之間進行數據共享)。
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 原型分析
原型:函數都有一個原型屬性prototype,該屬性值本質上也是對象(實際就是Object的實例)。
原型的作用:實現數據共享(實例對象之間進行共享);實現繼承。
__proto__
:構造函數產生的實例對象都有一個屬性__proto__
,該屬性不是標準屬性,不可以在編程中使用,實際上該屬性是瀏覽器內部使用的,該屬性和構造函數中的prototype指向相同。
__proto__
屬性在實例對象中,prototype屬性在構造函數中,這兩個屬性的指向是相同的。
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"]
//解釋:
//通過對象.屬性名稱=值 這種做法會向對象中添加一個屬性
//但是obj.arr.push(123); 這種結構不會再obj中添加屬性,而會obj.arr數組中添加一項數據
2.2 面向過程與面向對象
2.2.1 相關概念
-
面向對象是一種編程模式,就是以對象的方式寫代碼。
三大特性:封裝、繼承那個、多態。
面向過程的編程模式的缺點:團隊開發容易產生命名沖突;不方便代碼的重用;可維護性差。
-
JavaScript面向對象相關概念:
- 構造函數
- 實例對象
- 原型
2.2.2 面向對象開發
//實現如下功能:點擊一個按鈕改變div的背景色
//用面向對象的風格封裝(構造函數+原型)
function ChangeColor(btnId,divId){
this.btn = document.getElementById(btnId);
this.div = document.getElementById(divId);
}
ChangeColor.prototype.init = function(){
// 原型方法中的this指的是該原型所屬的構造函數的實例化對象,實際上與構造函數中的this指向相同
var that = this;//緩存實例對象
this.btn.onclick = function(){
// 這里的this是綁定事件函數的DOM對象
that.div.style.backgroundColor = 'yellow';
}
}
onload = function(){
var cc = new ChangeColor('btn','div1');
cc.init();
}
//不同的this場景:
//1、構造函數中的this
//2、原型方法中的this
//3、事件方法中的this
//1) 構造函數中的this和原型方法中的this指向相同:都是指向實例對象
//2)事件方法中的this指的是綁定事件的對象
2.2.3 對象中屬性的判斷
- in:判斷對象中是否存在某個屬性(屬性在實例對象和原型對象都可以)。
- hasOwnProperty():判斷屬性是否在實例對象上。
//小測試:
if('a' in window) {
var a = 123
console.log(a);
}
//輸出:123
//考點:
//1.全局作用域中的變量和函數都是window對象的成員
//2.預解析
//3.js中沒有塊級作用域
//實現一份方法,判斷某個屬性是否在原型上
function check(attr,obj){
if(attr in obj && !obj.hasOwnProperty(attr)){
return true;
}else{
return false;
}
}
2.3 構造函數、原型與實例的關系
2.3.1 構造函數、原型與實例的關系
- 構造函數中都有原型屬性prototype,該屬性值本質也是對象(Object的實例對象)
- 原型對象中都有一個屬性constructor,該屬性指向原型所屬的構造函數
- 實例對象中都有一個屬性
__proto__
,該屬性不是標準屬性,不可以在編程中使用,實際上是瀏覽器內部使用的,并且該屬性指向原型對象。
2.3.2 原型鏈
原型鏈:實例對象和原型對象之間形成的有限鏈式結構,該鏈式結構通過
__proto__
連接起來,用于實現繼承和共享屬性。-
對象是有原型對象的,原型對象也有原型對象,原型對象也有原型對象,對象的原型對象一直往上找,會找到一個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
-
原型鏈的結構可以通過重置原型對象的方式來修改。
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 繼承
繼承:別人的拿過來,自己的還是自己的。可以通過修改原型的指向來實現。
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);
缺點:沒有辦法給基礎過來的屬性賦值,而不影響所有的實例。繼承過來的引用類型的數據,所有的實例時共享的。
2.4.2 借用構造函數繼承
-
call和apply的基本使用:
- call和apply可以調用函數。
- 改變所調用函數內部的this指向。
- 在非嚴格模式下,普通函數中this是window;在嚴格模式下,普通函數中this是undefined。
-
借用構造函數繼承:
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構造函數的實例 // 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();
缺點:沒有辦法繼承父級構造函數原型上的成員。
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新特性,方法的作用:創建對象
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 函數
2.7.1 函數的原型鏈
-
Function:
- 所有的函數都是Function的實例。
- Funciton也是一個函數。
2.7.2 函數的三種角色
- 構造函數
- 普通函數
- 函數作為對象
function Foo(){}
var foo = new Foo(); //構造函數
Foo(); //普通函數
Foo.info = 'hello'; //函數作為對象
函數到底是哪種角色,取決于函數的調用方式
2.7.3 函數的定義方式
系統函數(類庫、庫函數)
-
自定義函數
-
函數聲明
function foo(){ console.log(123); }
-
函數表達式
var fn = function(){ console.log(456); } fn();
-
new Function()
var fn1 = new Function('console.log(789);');//需要把字符串轉成js代碼并執行,性能沒有前兩者好 fn1();
區別:
- 函數聲明是在預解析階段創建的,而函數表達式是在程序執行階段創建的。
- 函數聲明只能在全局或者函數內部定義,而函數表達式只能在表達式中定義。
-
函數都是對象,但對象不一定是函數。
Math不是函數,而是對象
2.7.4 this的不同指向場景
-
函數的調用方式:(函數中的this指向取決與函數的調用方式)
- 構造函數
- 普通函數
- 對象方法
- call和apply調用(bind)
-
this的不同指向:
- 構造函數中的this指向實例對象
- 原型方法中的this指向實例對象,與構造函數中的this指向相同
- 在非嚴格模式下,普通函數中的this指向window,在嚴格模式下,普通函數中的this指向undefined
- 對象方法中的this就是調用方法的對象
- 事件方法中的this指的是綁定事件的對象
- 定時函數中的this指的是window
- call或apply所調用的函數中的this就是call或apply中的第一個參數(該參數必須是引用類型)
-
bind的基本用法:
- bind方法是ES5的新特性(函數的柯里化)
- bind用來改變函數內部的this指向,但是不調用函數,并且bind會返回一個新函數(其實還是原來的函數內容,只是this改變為bind中的第一個參數,該參數必須為引用類型)
var inner = function(a,b){ console.log(a+b); } var newInner = inner.bind({info:'hello'},12,13); setTimeout(newInner,1000);
2.7.5 高階函數
高階函數:
-
作為參數的函數
function foo(fn) { var data = { info: 'hello' } fn(data); } var fn = function(data) { console.log(data.info); }; foo(fn);
-
作為返回值的函數(閉包)
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 對象的體系結構
- 所有的實例對象都有一個
__proto__
屬性,該屬性指向產生實例對象的構造函數的原型。 - 所有的構造函數都有一個prototype屬性,該屬性本質上也是一個對象(Object的實例對象)
- 所有的原型對象都有一個constructor屬性,該屬性指向原型所屬的構造函數。
- 原型對象中有一個
__proto__
屬性,該屬性指向Object.prototype(Object的原型對象中沒有__proto__
,因為這里就是原型鏈的終點) - 所有的函數都是Function的實例對象。
- Function函數本身也是它自己的實例對象(也就是
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 類數組(關聯數組)詳解
-
類數組:
var obj = { 0 : 'qqq', 1 : 'www', 2 : 'eee', length : 3 }
-
類數組轉數組:
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刪除。
-
求數組中的最大值:
//排序 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的應用場景:
- 調用函數
- 改變所調用函數的內部this指向
- 轉換類數組
- 借用別的對象方法
2.9 遞歸
2.9.1 遞歸的執行原理
function fn(n){
if(n == 1){
console.log('遞歸結束' + 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);
/* 輸出結果:
遞歸前5
遞歸前4
遞歸前3
遞歸前2
遞歸結束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];
//如果子節點是元素類型就放到數組中
if (subNode.nodeType == 1) {
arr.push(subNode);
//以當前子節點作為新的父節點繼續遞歸
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){
// 實現選擇器功能
// div .active #div1 div span .active div span
// Sizzle
var aDiv = document.getElementsByTagName(selector);
// 把每一個div都放到this中,那么this就是一個類數組
[].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');//設置樣式值
$('div').css({
width : '100px',
height : '100px'
});
$('div').css(['width','height']);//{width : 100px,height : 100px}
});
//待整理
2.10 作用域與閉包
2.10.1 作用域
作用域:指的是變量的作用范圍。
- 全局作用域
- 函數作用域
- js沒有塊級作用域
作用域鏈:鏈是一個對象列表(list of objects) ,用以檢索上下文代碼中出現的標識符(identifiers) 。標示符可以理解為變量名稱、函數聲明和普通參數。作用域鏈包括活動對象和父級變量對象。
- 函數內層作用域可以訪問外層作用,但是反過來不可以。
2.10.2 預解析
JavaScript解析器在執行代碼的時候分為兩個階段:
- 預解析
- 全局預解析(所有的變量和函數聲明都會提前;同名的函數和變量函數的優先級高)
- 函數內部預解析(所有的變量、函數和形參都會預解析,優先級:函數 > 形參 > 變量)
- 從上到下逐行執行
先預解析全局作用域,然后執行全局作用域中的代碼,在執行全局代碼的過程中遇到函數調用就會先進行函數預解析,然后再執行函數內的代碼。
2.10.3 閉包
閉包是一系列代碼塊(在ECMAScript中是函數),并且靜態保存所有父級的作用域。通過這些保存的作用域來搜尋到函數中的自由變量。
當一個函數在自身函數體內需要引用一個變量,但是這個變量并沒有在函數內部聲明(或者也不是某個參數名),那么這個變量就可以稱為自由變量[free variable]。
閉包:
- 封閉的區域
- 函數的嵌套形成閉包(內層函數和內層函數所處的作用域)
- 閉包可以操作函數內部的變量(間接的)
閉包的作用:
- 可以緩存中間狀態值
- 延長變量的生命周期
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 函數相關屬性補充
- arguments 表示實參的集合
- length 形參的個數
- caller 函數的調用者
- name 函數的名稱
- arguments.callee 表示函數本身,但是不推薦使用
2.11.2 事件處理機制
- 瀏覽器本身是單線程還是多線程?多線程(多進程)
- 頁面標簽的渲染
- 網絡通信
- 解析js的運行
- js的運行是單線程的
- 事件隊列(隊列中放什么?任務(實際上就是函數))
- 定時函數(延時時間到了)
- 事件函數(對應的事件觸發)
- Ajax的回調函數(接收到服務器完整的數據(readyState值發生變化的時候))
- 事件隊列中任務執行的條件:
- 主線程空閑
- 滿足任務的觸發條件
2.11.3 事件綁定方式
-
行內綁定
<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'); });
-
觸發事件
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 正則相關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
//從字符串中找出數字 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 正則的規則
- 元字符:
三、面試題
3.1 ==和===相關的比較問題
[] ==![] //true
[1] == [1] //false
[1] == ![1] //false
比較規則:
- 對象之間的比較是內存地址的比較
- 單個空對象轉成布爾值是true
- 空數組與布爾值的比較會轉換成數值的比較(空數組會轉化成0)
- 轉成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 以下代碼的輸出結果是什么?
var a = {n:1};
var b = a;
a.x = a = {n:2}; //運算符的優先級 .的優先級最高 賦值操作是從右向左運算的
console.log(a.x); //undefined
console.log(b.x); //{n:2}
考點:
- 基本類型和引用類型
- 引用類型變量和對象屬性(在內存實際上就是內存地址)
- 運算符的優先級
.
的優先級最高 ,賦值操作是從右向左運算的
3.4 下列代碼輸出結果是什么?
var a = {name:'zhangsan'};
var b = {age : 26};
var arr = [];
arr[a] = 123;
arr[b] = 456;
console.log(arr);//Array[0] -->[object Object]:456
數組也是對象
對象屬性的訪問方式
Object的toString方法作用:把構造函數轉成這種形式的字符串:[object Object]
3.5 跨域解決方案有哪些?
- jsonp
- cors
- 反向代理
- flash插件
3.6 DNS解析過程是什么?
- DNS Domain Name System : 負責域名和IP地址的映射關系
- 域名解析的規則:先去本機的hosts文件中查找IP,如果沒有找到,就去公網的DNS服務器查找,如果還沒有找到,那就無法上網;如果在hosts文件中找到了,那么就返回ip,就不再去公網查找了
3.7 前端有多少種方式可以發送請求?
1)瀏覽器地址直接輸入url
2)表單的action屬性
3)a標簽href屬性
4)img的src屬性
5)script的src屬性
6)link標簽的href屬性
7)iframe的src屬性
8)Ajax發送請求
9)postMessage h5新的API
10)flash插件也可以
11)location.href
url的規范格式:
scheme://host:port/path?query#fragment
echeme 表示協議 http https ftp file ssh
host 表示域名或者IP地址
port 端口 用來確定計算機上的具體某個網絡應用程序
path 域名之后,?之前的內容 /abc/qqq/rrr
query 查詢字符串,作用是向服務器傳遞數據,格式:鍵=值&鍵=值
fragment hash 錨點 定位頁面的某一部分