js學習之路----基礎

基礎

邏輯運算符

||   &&   !

1、|| 或,只要任意一個成立就返回true
在這裏插入圖片描述
2、 && 與,只要兩個同時成立才返回true,任一一個不成立,就返回false

在這裏插入圖片描述

3、! 非 返回相反的值

在這裏插入圖片描述

賦值運算

n ++; 相當於  n = n+1

n += int;加等於

在這裏插入圖片描述

n -= int; 減等於

在這裏插入圖片描述

	n *= int;乘等於

在這裏插入圖片描述

	n /= int;除等於

在這裏插入圖片描述

循環

for循環
var s1 = [1,2,3,4,'da','df','2'];
for (var i=0;i<s1.length;i++){
	console.log(i);
	console.log(s1[i])
	};

在這裏插入圖片描述

while 循環
var a = 10;
while (a <= 13){console.log("小於13",a);a++;console.log("等於13")}

在這裏插入圖片描述

三元運算
var a = 10;
var b = 20;
var c = a > b ? a : b       #如果a>b,那麼取a的值,反正取b的值

在這裏插入圖片描述

判斷

a = 10;
if (a>5){
	console.log('yes');
} else {
	console.log('no');
}

在這裏插入圖片描述

var a = 10;
if (a > 5){
  console.log("a > 5");
}else if (a < 5) {
  console.log("a < 5");
}else {
  console.log("a = 5");
}
switch 循環
var day = new Date().getDay();
switch (day) {
  case 0:
  console.log("Sunday");
  break;
  case 1:
  console.log("Monday");
  break;
default:
  console.log("...")
}

正則

創建一個匹配5-11位的以字母開頭的正則
var reg1 = new RegExp("^[a-zA-Z][a-zA-Z0-9_]{5,11}$");
var s1 = 'hello!';
var s2 = 'hao'
console.log(reg1.test(s1));  // 結果true
console.log(reg1.test(s2));  // 結果false

如果方便簡潔的話,還可以這樣寫。

console.log(/^[a-zA-Z][a-zA-Z0-9_]{5,11}$/.test('hello'));
console.log(/^[a-zA-Z][a-zA-Z0-9_]{5,11}$/.test(''));   //結果爲true
console.log(/^[0-9][a-zA-Z0-9_]{5,11}$/.test(''));   //結果爲false,因爲undefiend數字開頭
console.log(/^[a-zA-Z][a-zA-Z0-9_]{5,11}$/.test('undefiend'));   //結果爲true
因爲不填寫參數,默認會加一個undefiend,js會默認轉換爲undefiend字符串

替換

var s1 = 'Dasdadasd';
var s2 = s1.replace(/d/,'你好'); //g 全局替換,i忽略大小寫
console.log(s2);
結果:Das你好adasd
var s1 = 'Dasdadasd';
var s2=  s1.replace(/d/gi,'你好'); //g 全局替換,i忽略大小寫
console.log(s2);  
結果:你好as你好a你好as你好

正則坑:
1、表達式內一定不要有空格,否則無法識別。
2、如果正則匹配不傳參數,會默認傳一個undefiend,但是js會把undefiend當做一個字符串去匹配,因此匹配不到
3、正則表達式完成替換,不是替換原來的字符串,而是生成新的字符串,無法單純替換原來的字符串~

函數

# 函數的定義
普通函數
function foo(a,b){
    console.log(a);
    console.log(b)
}
#函數的調用
foo(1,2)
# 定義帶返回值的函數,加一個return即可
function foo(a,b){
    return a+b
}
# 調用有返回值的函數,只需要var 一個變量賦值接收這個返回值即可
var ret= foo(1,2)
console.log(ret)
結果爲3
# 匿名函數,沒有名稱的函數
function (a,b){
    console.log(a);
    console.log(b);
    return a+b
}
這種情況下,匿名函數無法調用,如果需要調用,需要var一個變量進行賦值即可
var func = function (a,b) {
	console.log(a);
	console.log(b);
	return a+b
}
如果調用,直接運行func即可
func(a,b)
# 立即執行函數
(function (a,b){
	console.log(a);
	console.log(b);
	var abc = "我是函數內部的變量,其他地方無法調用,只在函數內部生效"
}) (1,2);
a和b爲形參
12位實參

# 爲什麼需要立即執行函數
有些方法或者變量,只需要調用一次即可,因此寫一個立即執行函數,
假如有一個變量定義在立即執行函數中,其他的地方無法訪問這個變量的,
這樣就做到了隔離其他的調用、上面的例子abc,就無法在其他地方調用。

假如函數需要傳2個參數。但是隻傳遞了一個參數,那麼那個沒有進行傳遞的參數默認會是 undefined 
假如函數需要傳遞2個參數,但是傳遞了5個參數,這個函數是不會報錯的
舉例:
var abc = func (a,b){
	console.log("a的值爲:",a);
	console.log("b的值爲:",b);
} 
abc(1)
打印的結果爲
a的值爲:1
b的值爲:undefined

var abc = function(a,b,c) {
	console.log(arguments);
	console.log(arguments.length);
}
# 執行
abc(1,2,3)
console.log(arguments) 可以打印參數的結果

在這裏插入圖片描述

# 實現一個加法運算
function add(a,b,c) {
    console.log(arguments); //打印參數的鍵值
    console.log(arguments.length); //打印參數的長度
    var ret = 0;  //定義一個參數
    for (var i=0;i<arguments.length;i++){
        ret += arguments[i];   // 把ret+arguments[i]的結果繼續賦值給ret,以此循環
    }
    return ret;  //返回結果
}

console.log(add(1,2,3,4));   //不管多少參數,都不會報錯。

結果爲 10

作用域

函數作用域就近原則

var city = "上海";

function func(){
	var citt = "北京";
	function inner(){
	var city = "深圳";
	console.log(city);
	}
	inner();
}

調用 
func()  // 結果打印是 深圳
因爲就近原則

var city = "BeiJing";
function Bar() {
  console.log(city);
}
function f() {
  var city = "ShangHai";
  return Bar;
}
var ret = f();
ret();  // 打印結果是?

打印結果應該爲Beijing
因爲上面那個函數靠近上面定義的beijing,因此打印結果爲北京
//調用函數的時候,要往回找函數的定義階段,
//如果函數定義階段沒有數據,就去找全局變量
//首先直接f(),沒有打印,return調用bar函數,bar函數內沒有定義city,因此需要去全局變量中找
//如果全局變量沒有,則返回undefined

閉包


var city = "BeiJing";
function f(){
    var city = "ShangHai";
    function inner(){
        console.log(city);
    }
    return inner;
}
var ret = f();
ret();
//執行結果爲 ShangHai
// 調用 f(), 其實是執行的inner這個函數,因此f()函數return返回的是inner這個函數
//inner函數沒有定義city這個變量
//因此需要去inner外面去找,靠近inner,定義了一個city = "ShangHai" 因此輸出結果爲ShangHai
//如果函數內部沒有定義city,那麼就去全局變量中查找

js詞法分析

js執行函數的過程會先進行分析

當函數調用的前一瞬間,會先形成一個激活對象:Avtive Object(AO),並會分析以下3個方面:

1:函數參數,如果有,則將此參數賦值給AO,且值爲undefined。如果沒有,則不做任何操作。
2:函數局部變量,如果AO上有同名的值,則不做任何操作。如果沒有,則將此變量賦值給AO,並且值爲undefined。
3:函數聲明,如果AO上有,則會將AO上的對象覆蓋。如果沒有,則不做任何操作。

函數內部無論是使用參數還是使用局部變量都到AO上找。

var age = 18;
function foo(){
  console.log(age);   //函數經過分析,返現age開始沒有定義,生成一個undefined,於是不糊賦值,哪怕全局變量有定義age
  var age = 22;       //第一步,因爲沒有函數調用age,會生成一個AO.age = undefined
  console.log(age);	  //這裏就執行了age
}
foo();  // 問:執行foo()之後的結果是?
// 結果是先打印 undefined  後打印22
// 先詞法分析,後賦值,先分析 var,之後再進行賦值操作,如果var age ,後面有 function age進行調用,那麼會被覆蓋
// 總結就是先分析函數內部變量定義過程,先看參數,後看局部變量,最後看有沒有函數定義,後執行

var age = 18;
function foo(){
  console.log(age);
  var age = 22;
  console.log(age);
  function age(){     // 這裏有函數調用age,不會生成undefined,
    console.log("呵呵");
  }
  console.log(age);
}
foo();  // 執行後的結果是?
//先分析 AO賦值  
//第一個console.log(age); 一開始沒有定義,則爲undefined,後面var age = 22;定義了,則爲AO.age = undefined,之後 function age()覆蓋了第二步的 AO.age = undefined,變成了 AO.age = function(){}
//於是第一個age變成了 AO.age = function(){},第二個賦值了變成了22,第三個變成了 呵呵
第一個打印的,永遠是分析階段最後一個狀態,或者爲undefined 或者爲函數,第二步才真正執行。
參考
詞法分析過程:
1、分析參數,有一個參數,形成一個 AO.age=undefine;
2、分析變量聲明,有一個 var age, 發現 AO 上面已經有一個 AO.age,因此不做任何處理
3、分析函數聲明,有一個 function age(){...} 聲明, 則把原有的 age 覆蓋成 AO.age=function(){...};

最終,AO上的屬性只有一個age,並且值爲一個函數聲明

執行過程:
注意:執行過程中所有的值都是從AO對象上去尋找

1、執行第一個 console.log(age) 時,此時的 AO.age 是一個函數,所以第一個輸出的一個函數
2、這句 var age=22; 是對 AO.age 的屬性賦值, 此時AO.age=22 ,所以在第二個輸出的是 2
3、同理第三個輸出的還是22, 因爲中間再沒有改變age值的語句了

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

李文周
https://www.cnblogs.com/liwenzhou/p/8004649.html

小技巧:
f12,在console界面輸入
document.body.contentEditable=true

ctrl +shift +p 彈出瀏覽器的輸入框
在這裏插入圖片描述
可以截取瀏覽器內的屏幕截圖

即可修改頁面信息

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章