JavaScript基礎以及進階知識
- 2021 年 7 月 10 日
- 筆記
- javascript
JavaScript基礎知識回顧:
目錄:
- 比較運算符
- 多行字元串,模板字元串
- 嚴格模式
- 函數定義和調用
- 變數作用域與解構賦值、NameSpace、塊級作用域let、const
- 方法
- 高階函數
- 閉包
我們一個一個慢慢來:
比較運算符:
-
= 如果1=』1』,則為false
-
== 等於 類型不一樣,值一樣,也會判斷為true
-
=== 絕對等於,類型一樣,值一樣,判斷為true
-
!== 不等於
-
這是js的缺陷,盡量不使用==比較
浮點數問題:
console.log((1/3)===(1-2/3))
結果為false,儘管數值是都等於1/3
盡量避免使用小數計算,因為精度問題
ES6中的模版字元串:
在新行中插入的任何字元都是模板字元串中的一部分,使用普通字元串,你可以通過以下的方式獲得多行字元串:
console.log('string text line 1\n' +
'string text line 2');
“string text line 1
string text line 2″
要獲得同樣效果的多行字元串,只需使用如下程式碼:
console.log(`string text line 1
string text line 2`);
“string text line 1
string text line 2″
插入表達式:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
var a=10;
var b = 20;
console.log(`a = ${a},b = ${b}`);
</script>
</body>
</html>
通過上述程式碼可知,需要把表達式${}放入到“中才能正確執行。
詳細說明:MDN
嚴格模式:
嚴格模式對正常的 JavaScript語義做了一些更改。
- 嚴格模式通過拋出錯誤來消除了一些原有靜默錯誤(undefined)。
- 嚴格模式修復了一些導致 JavaScript引擎難以執行優化的缺陷:有時候,相同的程式碼,嚴格模式可以比非嚴格模式下運行得更快。
- 嚴格模式禁用了在ECMAScript的未來版本中可能會定義的一些語法。
'use strict';
function getAge(){
var y = new Date().getFullYear();
return y - this.birth;
}
var xiaoming = {
name:'小明',
birth:2000,
age:getAge
};
//開不開啟use strick 結果不一樣
var fn = xiaoming.age;
console.log(fn());
具體鏈接:MDN
函數定義和調用:
定義函數方式:
定義方式一
絕對值函數
function abs(x){
return x;
}else{
return -x;
}
一旦執行到return代表函數結束,返回結果
定義方法二
var abs = function(x){
return x;
}else{
return -x;
}
function(x){}是一個匿名函數,可以把結果賦值給abs,通過abs就可以調用函數
方法一和方法二等價
調用函數:
abs(10)
abs(-10)
參數問題:javascript可以傳任何個參數,也可以不傳參數
參數進來是否存在的問題?假設不存在參數,如何拋出異常?
var abs = function(x){
//手動拋出異常來判斷
if (typeof x !== 'number') {
throw 'not a number';
}
if (x>=o) {
return x;
}else{
return -x;
}
}
arguments對象:
加入函數的實參沒有寫多個,但使用時傳入了多個參數,使用arguments對象可以把這多個參數用數組返回,argument對象其實就是傳入的所有參數的數組。
特性:
1.arguments對象和Function是分不開的。
2.因為arguments這個對象不能顯式創建。
3.arguments對象只有函數開始時才可用。
使用方法:
雖然arguments對象並不是一個數組,但是訪問單個參數的方式與訪問數組元素的方式相同
例如:
arguments[0],arguments[1],。。。arguments[n];
在js中 不需要明確指出參數名,就能訪問它們,例如:
function test() {
var s = '';
for (var i = 0; i < arguments.length; i++) {
alert(arguments[i]);
s += arguments[i] + ',';
}
return s;
}
test("name", "age");
結果為name,age
rest參數
例如:函數定義了兩個參數,但是傳入了第三個參數,要怎麼取出第三個參數呢?
function test(a,b){
console.log('a->'+a);
console.log('b->'+b);
//以前的方法取第三個元素:
if (arguments.length>2) {
for(var i = 2; i<arguments.length;i++){
console.log(arguments[i])
}
}
}
//現在的方法(rest參數):在函數中定義rest參數
function test1(a,b,...rest){
console.log('a->'+a);
console.log('b->'+b);
console.log(rest);
}
變數的作用域:
變數的作用域:
function a(){
var x = 1;
//內部函數可以訪問外部函數的成員,反之不行
function aa(){
var y = x +1; //2
}
//外部訪問了內部函數的變數,會不行
var z = y+1; //報錯
}
function foo(a,b){
var x = 1;
function bar(){
var x = 'A';
console.log(x);
}
console.log(x);
bar();
}
foo();
結果: 1 A
全局對象window
'use strict';
window.alert('調用Windows.alert');
var old_alert = window.alert;
window.alert = function(){
alert('無法使用alert方法');
}
window.alert = old_alert;
alert('又可以使用alert方法了');
調用的結果:只執行了兩次,第一次輸出–>調用Windows.alert;第二次輸出–>又可以使用alert方法了
Let關鍵字:
局部作用域let
ES6let關鍵字,解決局部作用域衝突問題,現建議大家都用let去定義局部變數
function aaa() {
for(vari=0;i<100;i++){
console.log(i)
}
console.log(i+1); //問題? i 出了這個作用域還可以使用
}
//使用let後
function aaa() {
for(leti=0;i<100;i++){
console.log(i)
}
console.log(i+1); //Uncaught ReferenceError: i is not defined
}
const關鍵字:
在ES6之後,用const定義常量;
const PI = '3.14';
console.log(PI);
PI = '123'; //報錯,常量不允許修改
命名空間NameSpace:
防止重名以及命名污染的現象發生;
var MYAPP = {};
var MYAPP2 = {};
MYAPP.name = 'myapp';
MYAPP.version = '1.0';
MYAPP.foo = function(){
console.log("測試");
};
MYAPP.foo();
MYAPP2.name = 'myapp';
MYAPP2.version = '1.0';
MYAPP2.foo = function(){
console.log("測試2");
};
MYAPP2.foo();
方法:
定義方法
方法就是把函數放在對象的裡面,對象只有兩個東西:屬性和方法
var xiaoming = {
name:'小明',
birth:2000,
age:function(){
var y = new Date().getFullYear();
return y -this.birth;
}
};
console.log(xiaoming.age());
成員屬性只對子方法負責,不對孫方法負責。
var xiaoming = {
name:'小明',
birth:2000,
age:function (){
//保存xiaoming這個對象
var that = this;
function getAgeFromBirth(){
var y = new Date().getFullYear();
//如果不保存,這裡是找不到birth屬性的
return y - that.birth;
}
return getAgeFromBirth();
}
}
console.log(xiaoming.age());
為了解決上面這個缺陷:我們引入了apply關鍵字;
apply方法是可以控制this指向的,該方法有兩個參數,第一個是getArg要使用的是那個對象,第二個是數組;
//解決的js的缺陷
function getAge(){
var y = new Date().getFullYear();
return y - this.birth;
}
var xiaoming = {
name:'小明',
birth:2000,
age :getAge
};
//apply(x,y);
//第一個參數是getAge中this的所需要的指向(不指向為null)
//第二個參數默認是數組格式,表示傳入的參數類型
console.log(getAge.apply(xiaoming,[]));
高階函數使用:
map、reduce、filter
map:實現每個數平方
function pow(x){
return x * x;
}
var arr = [1,2,3,4,5,6,7,8,9];
var result = arr.map(pow);
console.log('='+result);
reduce:實現累加
var arr = [1,2,3,4,5];
//1+2-->3 x
//x+4-->7 x
//x+5-->12 x
var result = arr.reduce(function(x,y){
return x+y;
});
console.log(result);
filter:過濾掉不符合函數要求的值
var arr = [1,2,3,4,5,6,7];
var r = arr.filter(function(x){
return x%2 !== 0;
});
console.log(r);
閉包:
閉包的引入:
//函數內部可以訪問全局變數
var n = 999;
function f1(){
console.log(n);
}
//外部訪問不了函數內部的變數
function f1(){
var n = 999;
}
console.log(n);
使用閉包來實現外部引用內部資訊:
function f1(){
var n = 999;
function f2(){
console.log(n);
}
return f2;
}
var res = f1();
res();
複雜閉包的實現:
//閉包複雜程式碼段
function createIncermentor(start){
return function(){
return start++;
};
}
var inc = createIncermentor(10);
console.log(inc());
console.log(inc());
console.log(inc());
結果:10 11 12
定義類:
function Person(){
var _age;
function setAge(n){
_age = n;
}
function getAge(){
return _age;
}
//{} //var obj = {}是對象
return {
name:name,
getAge:getAge,
setAge:setAge
};
}
var p1 = Person("xbhog");
p1.setAge(88);
console.log(p1.getAge());
結果:88
感覺可以的朋友,可以給我點點關注或者推薦,感謝!