【前端】JavaScript基本语法

103 阅读3分钟

1. JavaScript引入

内部标签

<script>
    alert("Hello World!");
</script>

外部引入

<script src="scripts/script.js"></script>

2. 数据类型

变量

var $a = 1;
var _b = "a";
var 小鱼儿 = NaN;

number

123       // 整数
123.123	  // 浮点数
1.23e3    // 科学计数法
-99       // 负数
NaN       // not a number
Infinity  // 表示无限大

字符串

'abc'
"abc"

布尔值

console.log(2 > 1);  // true

逻辑运算

console.log(true && true);
console.log(true || false);
console.log(!true);

比较运算符

=	 /*赋值*/	
    
==   /*等于*/
console.log(1 == "1");    		   // true

===  /*绝对等于*/
console.log(1 === "1");   		   // false
console.log(NaN === NaN);                  // false
isNaN(NaN);
console.log((1/3) === 1 - (2/3));          // false
console.log(Math.abs(1/3 - (1 - 2/3)) < 0.000000001);  // true

null 和 undefined

  • null
  • undefined 未定义

数组

var arr = [1, "abc", 1.2, false, null];
console.log(arr[0]);
console.log(arr[5]);  // undefined

对象

var person = {
    name: "LittleFish",
    age: 1,
    tags: ["js", "python", "c++", "..."] // 不需要逗号
}
console.log(person.name);
console.log(person.tags[0]);

use strict

严格检查模式,预防JavaScript的随意性导致产生的一些问题

局部变量用 let

3. 字符串类型

转义

console.log('a\'b');
/*
   \n
   \t
   \u4e2d
   \x41
*/

多行字符串

var msg = `滚滚长江东逝水
           浪花淘尽英雄`;
"滚滚长江东逝水\n\t\t   浪花淘尽英雄"

模板字符串

let name = "LittleFish";
let age = 1;
let msg = `Hello, ${name}`;

字符串长度

var student = "student";
console.log(student.length);
console.log(student[0]); // string不可变性

大小写转换

console.log(student.toUpperCase());
console.log(student.toLowerCase());

其他方法

console.log(student.indexOf("u"));
console.log(student.substring(1, 3));

4. 数组类型

var arr = [1, 'a'];
arr[0] = 2;

长度

arr.length;
arr.length = 3;
// [1, "a", empty]
arr.length = 1;

其他方法

arr.indexOf('a');
arr.slice(0, 1);
arr.slice(1);
arr.push(1.2);  // [1, "a", empty, 1.2]
arr.pop();
arr.shift();
arr.unshift(false);
var arr = ['a', 'A', 'b'];
arr.sort();
// (3) ["A", "a", "b"]
arr.reverse();
// (3) ["b", "a", "A"]
arr.concat([1, 2, 3]);
// (6) ["b", "a", "A", 1, 2, 3]
arr;
// (3) ["b", "a", "A"]
arr.join('-');
// "b-a-A"
arr;
// (3) ["b", "a", "A"]

多维数组

arr = [[1, 2], [3, 4], ["5", "6"]];
arr[1][1];

5. 对象类型

var person = {
    name: "LittleFish",
    age: 1,
    tags: ["js", "python", "c++", "..."] // 不需要逗号
}

对象赋值

person.name = "小鱼儿";
person.name;
person.Name;
undefined

动态增删

delete person.name;
true
person;
{age: 3, tags: Array(5)}
person.ID = "LittleFish";
person;
{age: 3, tags: Array(5), ID: "LittleFish"}

判断属性是否在对象中

'age' in person;
true
'toString' in person;
true

判断一个属性是否是这个对象自身拥有的

person.hasOwnProperty('age');
true
person.hasOwnProperty("toString");
false

6. 分支和循环

判断

和C++一样

var age = 12;
if (age < 10) {
    console.log('C');
} else if (age < 20) {
    console.log('B');
} else {
    console.log('A');
}

循环

while (age < 30) {
    age++;
    if (age % 5 == 0)
    	console.log(age);
}
do {
    if (age % 6 == 0) {
        console.log(age);
    }
    age++;
} while (age <= 30);
for (var age = 12; age <= 30; age++) {
    if (age % 5 == 0)
        console.log(age);
}
var age = [5, 10, 15, 20, 25, 30, 35];
age.forEach(
    function (value) {
        console.log(value / 5);
    }
)
for (var num in age) {
    console.log(num, age[num]);
}

7. Map和Set

Map

var map = new Map([['Tom', 100], ["Jack", 94], ["Rose", 96]]);
var score = map.get("Rose");  // 96

map.set('Amy', 99);  
// Map(4) {"Tom" => 100, "Jack" => 94, "Rose" => 96, "Amy" => 99}

map.delete("Tom");
// Map(3) {"Jack" => 94, "Rose" => 96, "Amy" => 99}

Set

var set = new Set([1, 2, 3, 3, 2, 1]);
Set(3) {1, 2, 3}

set.add(0);
Set(4) {1, 2, 3, 0}

set.delete(3);
Set(3) {1, 2, 0}

console.log(set.has(1));

8. 迭代

遍历数组

var arr = [3, 4, 5];
for (var x of arr) {
    console.log(x);
}

遍历Map

for (let x of map) {
    console.log(x);
}

(2) ["Jack", 94]
(2) ["Rose", 96]
(2) ["Amy", 99]

遍历Set

for (let x of set) {
    console.log(x);
}

9. 函数

函数定义

定义方式一

function abs(x) {
    if (x >= 0) {
        return x;
    } else {
        return -x;
    }
}

定义方式二

var abs = function(x) {
    if (x >= 0) {
        return x;
    } else {
        return -x;
    }
}

参数个数问题

抛出异常

function abs(x) {
    if (typeof x != 'number') {
        throw 'Not a Number';
    }
    if (x >= 0) {
        return x;
    } else {
        return -x;
    }
}

abs('a')
Uncaught Not a Number

arguments 表示传递进来的所有参数,是一个数组!

function test(x) {
    console.log("x =>", x);
    for (var i = 0; i < arguments.length; i++) {
        console.log(arguments[i]);
    }
}

test(1,2)
x => 1
1
2

test(1,[2,3])
x => 1
1
(2) [2, 3]

rest rest必须写在最后面,用...标识

function test(a, ...rest) {
    console.log("a =>", a);
    for (var i = 0; i < rest.length; i++) {
        console.log(rest[i]);
    }
}

test(1,2,[3,4]);
a => 1
2
(2) [3, 4]

10. 变量作用域

假设在函数体中声明,则在函数体外不可以使用

function test() {
    var x = 1;
    x = x + 1;
}
x = x + 1; 

如果两个函数使用了相同的变量名,只要在函数内部,就不冲突

function f1() {
    var x = 1;
    x = x + 1;
}
function f2() {
    var x = 'A';
    x = x + 1;
}

内部函数可以访问外部函数的成员,反之则不行

function f1() {
    var x = 1;
    function f2() {
        var y = x + 1;
    	console.log(y);
    }
    f2();
}

内部函数和外部函数的变量重名

function f1() {
    var x = 1;
    function f2() {
        var x = 'A';
        console.log('inner', x);
    }
    f2();
    console.log('outer', x);
}

提升变量的作用域

说明:js执行引擎,自动提升了 y 的声明,但是不会提升变量 y 的赋值。

function f1() {
    var x = "x" + y;
    console.log(x);
}
f1();
Uncaught ReferenceError: y is not defined

function f2() {
    var x = "x" + y;
    console.log(x);
    var y;
}
f2();
xundefined

养成规范:所有的变量定义都放在函数的头部,便于代码维护。

function f() {
    var x = 1,
        y = 'a',
        z = [true, false];
    // ...
}

全局变量

var x = 1; // 全局变量
function f() {
    console.log('local', x);
}
f();
console.log('global', x);

全局对象window

var x = 'A';
console.log('console.log', window.x);
window.console.log('window.console.log', window.x);
// 默认所有的全局变量,都会自动绑定在window对象下
window.alert(1);
var old_alert = window.alert;
window.alert = function() {}
/*window.alert(2);*/
window.alert = old_alert;
window.alert(3);

规范,为了减少冲突

把自己的代码全部放入自己定义的唯一全局变量中,降低全局变量命名的冲突。

// 唯一全局变量
var LittleFish = {};

// 定义全局变量
LittleFish.gender = 'female';
LittleFish.age = '3';
LittleFish.hello = function() {
    console.log("Hello World!");
}

局部作用域

function f() {
    for (var x = 0; x < 5; x++) {
	console.log(x);
    }
    console.log(x);  // x还是可以打印出来
}
function f() {
    for (let x = 0; x < 5; x++) {
	console.log(x);
    }
    // console.log(x); 报错
}

建议使用 let 定义局部作用域的变量

常量

const PI = '3.14';
console.log(PI);
// PI = '3.14159'; Uncaught TypeError: Assignment to constant variable.

11. 方法的定义和调用

方法就是把函数放在对象里面。

// 唯一全局变量
var LittleFish = {
    name: '小鱼儿',
    birth: 2020,
    age: function () {
        var now = new Date().getFullYear();
        return now - this.birth;
    }
};

console.log(LittleFish.age());

this 默认指向调用它的那个对象

function getAge() {
    var now = new Date().getFullYear();
    return now - this.birth;
}
getAge(); // NaN, window对象下没有birth

var birth = 2020;
getAge();  // 2, 现在有了

apply 控制 this 指向

LittleFish.birth = 2024;
getAge.apply(LittleFish, []);