變數宣告
var 特點:
1.可以重複宣告
2.不能定義常量
3.不支援塊級作用域
複製程式碼
- let
//1.不存在預解釋 變數提升
//2.暫時性死區
//3.具備塊級,同一塊內不能重複宣告;
let a ={name:'xiaoming'}
if(true){
let a = 'xiaohong';//不同塊,可以宣告相同名;
}
console.log(a) //{name:'xiaoming'}
if(true){
let v= '20130401'
}
console.log(v) //報錯:v is not defined
for(var i=0;i<3;i++){//i是全域性的
//閉包
(function(i){
setTimeout(function(){
console.log(i)
})
})(i)
}
//用let
for(let i = 0;i<3;i++){//i是塊級的
setTimeout(function(){
console.log(i)
},1000)
}
複製程式碼
- const
//不存在預解釋、變數提升
//不能重複定義宣告
//不能更改他的值。
//具備塊級
const str = 123;
str = 3445;//報錯:常量不能重新賦值
const = obj = {name:'xiaoming'}
obj.name= 'xiaohong';//可以修改;const限制的是不能給變數重新賦值,給變數的屬性修改,實際並未修改記憶體地址。
複製程式碼
解構
解構就是分解一個物件的解構,可以用一種類似陣列的方式定義n個變數,可以將一個陣列中的值按照規則賦值過去。
解構的時候,等號兩邊結構類似;左邊物件右邊就是物件;左邊資料右邊也得是陣列,右邊還必須是一個真是存在的值;
複製程式碼
- 陣列、物件的簡單解構賦值
var arr = [1,2,3]
var [a,b,c] = arr; // a=>1 b=>2 c=>3
var obj = {a:1,b:2}
var {a,b} = obj; //物件解構,根據key解構,a=>1,b=>2
var {a:a1,b:b1} = obj;// 物件解構,不用key作為變數名,指定變數名; a1=>1 b1=>2
複製程式碼
- 巢狀解構賦值
var arr = [{a:1,b:2},[3,4],5]
var [{a,b},[c,d],e] = arr; //結構一樣,a=1 b=2,c=3,d=4,e=5
var [obj,ary,n] = arr ; //整合起來賦值,obj= {a:1,b:2} ary=[3,4] n=5
複製程式碼
- 預設賦值解構;如果能取到值就用取到的,取不到(undefined)時就用預設的值;
var obj = {a:1}
var {a,b} = obj;
console.log(b)//undefined
var {a,b=2} = obj;
console.log(b)//2
var ary = [1,,3]//ary[1] = undefined
var [a = "a", b = "b", c =new Error('C必須指定')] = ary;
console.log(a, b, c);// 1,b,3
function ajax(options){
var method = options.method || 'get'
var data = options.data || {}
...
}
函式宣告形參利用解構賦值+預設賦值
function ajax({method='get',data={}){
//函式傳參解構賦值,相當於let了這個變數;
console.log(method,data)
}
ajax({
method:'get',
data:{id:1}
})
複製程式碼
- 省略賦值
var arr = [1,2,3]
var [,,j] = arr;
console.log(j)//3 只想取出陣列最後一個
複製程式碼
模版字串
- 1.可以巢狀變數
- 2.支援換行
- 3.可帶一個標籤屬性進行描述,因為我們希望有時候在拼接字串的時候有自己的邏輯
var name = 'xiaoming',age = 9;
var str = `${name}今年${age}歲`
var str1= `${name}
今年${age}歲
`console.log(str)
console.log(str1)
//把老陣列中的每一個元素應設為新陣列中的每一個元素
var users = [{id:1,name:'zfpx1'},{id:2,name:'zfpx2'}]
var newUser = users.map(item=>{
return `<li>${item.id}:${item.name}</li>`
})
let str = (`
<ul>
${newUser}
</ul>
`)
console.log(str)
//描述
//帶標籤的模版字串就像一個函式呼叫
//引數:第一個引數是文字的陣列,剩下的依次是模版字串中出現的變數值;可以用剩餘運算子收攏起來
//strings 文字的陣列 指的是 模版字串被變數分割出來的陣列。
function desc(strings,...rest){
let result = '';
for(let i =0;i<rest.length;i++){
result +=(strings[i]+rest[i])
}
result += strings[strings.length-1] //strings是被變數分割出來的,所以長度比rest多一個;
return result;
}
var str = desc`${name}今年{age}歲了`
//str就是desc的返回值
面試:模版字串(ejs等字串模版通用原理)的原理:正則匹配-分組捕獲-替換
var name = 'xiaoming',age = 9;
var tem = "${name}今年${age}歲了";
function replace(tem){
return tem.replace(/\$\{(\w+)\}/g,function(...args){
//args[0] 匹配到的整個串
//args[1] 第一個分組捕獲的
return eval(args[1]);//替換匹配到的整個串
})
}
console.log(replace(tem))
複製程式碼
字串新增的方法
- includes 是否包含
- startsWith 是否以什麼開頭
- endsWith 是否以什麼結尾
- repeat 重複多少遍,返回新的字串
let address1 = 'http://www.baidu.com'
let address2 = 'ftp://www.baidu.com'
if(address1.startsWith('http')){
console.log('http網址')
}else if(address1.endsWidth('http')){
console.log('ftp服務')
}
let filename = 'avatar.jpg';
if(filename.endsWith('jpg') || filename.endWith('png')){
console.log('圖片')
}
let str = 'zfpx'
str.includes('z')//true 包含
let str2 = str.repeat(3);// zfpxzfpxzfpx 重複三遍,返回新的字串
複製程式碼
func方法(函式傳參、接收引數、剩餘運算子、展開運算子)
- 預設引數:可以指定預設值,沒傳的話(undefined)就用預設值;指定必傳引數,不傳報錯;解構賦值引數; function ajax(url=new Error('url不能為空'),method='get',dataType='json'){ console.log(url) console.log(method) console.log(dataType) } function ajax1({url=new Error('url不能為空'),method='get',dataType='json'}){ console.log(url) console.log(method) console.log(dataType) }
ajax('/user') ajax1({ url:'/user' })
- 剩餘操作符,函式接收引數時使用,只能作為函式的最後一個接收引數使用;
//求和
function sum(prefix,...rest){
let n = rest.reduce((prev,next,nextIndex,origin)=>{
return prev+next;
})
return prefix+n
}
sum('$',1,2,3,4)
//求平均值
function fn(...rest){
return rest.reduce((prev,next,nextIndex,origin)=>{
let sum = prev+next;
if(nextIndex == origin.length-1){
return sum/origin.length;
}else{
return sum;
}
})
}
fn(1,2,3,4)
複製程式碼
- 展開運算子(淺拷貝、合併物件、函式入參)
//陣列
var arr1 = [1,2,3]
var arr2 = [4,5,6]
var arr3 = [...arr1,...arr2]
var arr4 =arr1.concat(arr2)
//物件
var obj1 = {a:1,b:2}
var obj2 = {c:3,d:4}
var obj3 = {
...obj1,
...obj2
}
var obj4 = Object.assign({},obj1,obj2)
//函式入參
function sum(a,b,c){
return a+b+c
}
sum(...arr1)
Math.max(1,2,3)
Math.max.apply(null,arr1)
Math.max(...arr1)
前端面試擴充套件:
//深拷貝、淺拷貝
淺拷貝: ...展開運算子、Object.assign
深拷貝:
JSON.parse(JSON.stringify({home:{city:'beijing'}))
function deepClone(origin){
let result;
if(origin instanceof Array){
result = [];
for(let i=0;i<origin.length;i++){
result.push(deepClone(origin[i]))
}
}else if(origin instanof Object){
result = {};
for(let key in origin){
result[key] = deepClone(origin[key])
}
}else{
result = origin
}
return result;
}
//reduce 的原理
//reduce 支援兩個引數:第一個引數是函式,第二個引數是初始值(不傳的話預設是陣列第一項)
//主要原理 就是 上一次的執行結果是下一次的初始值。
var arr = [1,2,3,4]
arr.reduce((prev,next,nextIndex,origin)=>{
return prev +next
},10) //初始值是10,第一次呼叫prev是10,next是1,nextIndex是0, 最後得到的結果是20
Array.prototype.myReduce = function(cb,initVal){
var prev,nextIndex;
if(typeof initVal =='undefined'){
//沒傳的話,初始值是陣列第一項,next的索引是1
prev = this[0];
nextIndex = 1;
}else{
//傳了的話,初始值是傳入的,next的索引是0
prev = initVal;
nextIndex = 0;
}
for(var j = nextIndex;j<this.length;j++){
prev = cb(prev,this[j],j,this)//執行結果是下一次的初始值。
}
return prev;
}
複製程式碼
arrow箭頭函式
- this指向上一級作用域的this
- 沒有arguments
var sum = function(a,b){
return a+b;
}
//如果只有返回值,沒有函式題程式碼,則可以省略{}
var sum1 = (a,b)=>a+b;
sum1(1,2)
////如果有且只有一個引數,可以省略小括號;
var double = num =>num*2
console.log(double(2))
//this問題, 箭頭函式沒有this,他會使用上級作用域的的this;
let obj = {
name:'zfpx',
getName(){
console.log(this.name)//this=>obj
}
}
obj.getName()
-------
let obj2 = {
name:'zfpx',
getName(){
//this=>obj
setTimeout(function () {
console.log(this.name)//this=>window, undefined
},1000)
}
}
obj2.getName()
---
let obj3 = {
name:'zfpx',
getName(){
//this=>obj
setTimeout( ()=> {
//箭頭函式沒有this,他會使用上級作用域的的this
console.log(this.name)//this=>obj, zfpx
},1000)
}
}
obj3.getName()
---
let obj4 = {
name:'zfpx',
getName:()=>{
console.log(this.name,11111) //this =>window, undefined
}
}
obj4.getName()
//箭頭函式的this是定死的,在定義時就定死了,不管在哪裡調,不管誰去調,this都是定義時的外層作用域的this
var obj5 = {
name:'zfpx',
getName:()=>{
console.log(this.name) //this =>window, undefined
}
}
var obj6 = {};
obj6.getName = obj5.getName;
obj6.getName();
複製程式碼