314 lines
10 KiB
Markdown
314 lines
10 KiB
Markdown
|
---
|
|||
|
title: JavaScript 基础语法
|
|||
|
date: 2020-10-18
|
|||
|
author: ac
|
|||
|
tags:
|
|||
|
- JavaScript
|
|||
|
categories:
|
|||
|
- Web
|
|||
|
---
|
|||
|
|
|||
|
## JavaScript 基础
|
|||
|
|
|||
|
### 变量和数据类型
|
|||
|
|
|||
|
JavaScript 的变量名区分大小写,A和a是两个不同的变量。声明变量的标识符不能以数字开头,字符集为Unicode。如果一个变量只是声明而没有被赋值,则该变量的值为underfined。
|
|||
|
|
|||
|
所有的数据都是用var定义。
|
|||
|
|
|||
|
```javascript
|
|||
|
var name = "admin";
|
|||
|
var age = 26;
|
|||
|
var obj = new Date();
|
|||
|
```
|
|||
|
|
|||
|
> 如果使用var声明一个已经存在的变量,是无效的,但如果并进行了赋值,则会覆盖掉前面的值
|
|||
|
>
|
|||
|
> ES6中新增了let、const 定义变量
|
|||
|
|
|||
|
**变量提升**
|
|||
|
|
|||
|
JavaScript 引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的【声明语句】(var a;),都会被提升到代码的头部,这就叫做变量提升(hoisting)
|
|||
|
|
|||
|
**区块(block)**
|
|||
|
|
|||
|
```javascript
|
|||
|
{
|
|||
|
var a=1;
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
区块对于var命令不构成单独的作用域,与不使用区块的情况没有任何区别。
|
|||
|
区块通常搭配更复杂的语法结构一起使用如:for、if、while
|
|||
|
|
|||
|
**作用域**
|
|||
|
|
|||
|
ES5中只有两种作用域,全局作用域、函数作用域,ES6中增加了块级作用域。
|
|||
|
|
|||
|
函数内部定义的变量,会在该作用域内覆盖同名全局变量。
|
|||
|
|
|||
|
对于var命令来说,局部变量只能在函数内部声明,在其他区块中声明,一律都是全局变量。即函数内部用var声明的变量是局部变量,但像if、switch、for这些{}用var声明的是全局变量。函数执行时所在的作用域,是定义时的作用域,而不是调用时所在的作用域。
|
|||
|
|
|||
|
**数据类型**
|
|||
|
|
|||
|
number、string、boolean、undefined、null、object
|
|||
|
|
|||
|
- 原始类型:number/string/boolean
|
|||
|
- 合成类型:object(狭义的对象Object、数组Array、函数function)
|
|||
|
- 特殊值 :undefined/null
|
|||
|
|
|||
|
typeof元运算符,返回跟在其后面变量的数据类型的字符串。
|
|||
|
|
|||
|
```javascript
|
|||
|
typeof 123 // "number"
|
|||
|
typeof '123' // "string"
|
|||
|
typeof false // "boolean"
|
|||
|
|
|||
|
function f() {}
|
|||
|
typeof f // "function"
|
|||
|
|
|||
|
typeof undefined // "undefined" undefined返回undefined。没有声明的变量也为undefined
|
|||
|
|
|||
|
typeof window // "object"
|
|||
|
typeof {} // "object"
|
|||
|
typeof [] // "object" 数组本质上只是一种特殊的对象,instanceof运算符可以区分数组和对象
|
|||
|
|
|||
|
typeof null // "object"
|
|||
|
```
|
|||
|
|
|||
|
|
|||
|
|
|||
|
**undefined和null的区别**:
|
|||
|
|
|||
|
- null是一个表示“空”的对象,转为数值时为0;
|
|||
|
- undefined是一个表示”此处无定义”的原始值,转为数值时为NaN。
|
|||
|
|
|||
|
```javascript
|
|||
|
Number(null) // 0
|
|||
|
Number(undefined) // NaN
|
|||
|
```
|
|||
|
|
|||
|
> parseInt逐个解析字符,而Number函数整体转换字符串的类型
|
|||
|
|
|||
|
**返回undefined的典型场景**:
|
|||
|
|
|||
|
1. 变量声明了,但没有赋值
|
|||
|
2. 调用函数时,应该提供的参数没有提供,该参数等于 undefined
|
|||
|
3. 对象没有赋值的属性
|
|||
|
4. 函数没有返回值时,默认返回 undefined
|
|||
|
|
|||
|
|
|||
|
|
|||
|
**隐式布尔型:**
|
|||
|
|
|||
|
当预期某个位置应该是布尔值,会将该位置上现有的值自动转为布尔值
|
|||
|
|
|||
|
- "": false,对于任何非空字符串都是 true.
|
|||
|
- 0: false,对于任何非0数值都是 true.
|
|||
|
- null: false,对于任何非空对象都是 true.
|
|||
|
|
|||
|
### 对象
|
|||
|
|
|||
|
#### Object对象
|
|||
|
|
|||
|
<div style='color:red'>JS原生提供Object对象,JS中的所有其他对象都继承自Object对象。</div>
|
|||
|
|
|||
|
> 其他对象指的是调用对象的toString()方法返回"[object Object]"的对象。第二个Object是该对象创建时使用的构造函数,可以是Number、String、Boolean、Undefined、Null、Array、Arguments、Function、Error、Date、RegExp、Object。
|
|||
|
|
|||
|
本身方法:直接定义在Object对象上的方法。
|
|||
|
|
|||
|
实例方法:定义在Object原型对象Object.prototype上的方法。
|
|||
|
|
|||
|
在Object.prototype对象上面的属性和方法,将被所有实例对象共享。
|
|||
|
|
|||
|
|
|||
|
|
|||
|
**构造函数与Object()**
|
|||
|
|
|||
|
作为构造函数使用new关键字创建新的对象。
|
|||
|
|
|||
|
```javascript
|
|||
|
var obj = new Object();
|
|||
|
```
|
|||
|
|
|||
|
> 通过var obj = new Object()的写法生成新对象,与字面量的写法var obj = {}是等价的。
|
|||
|
|
|||
|
`Object`本身也是一个函数,Object(arg)将参数arg转为对象,如果参数为空或是undefined和null,则返回空的对象
|
|||
|
|
|||
|
但Object(value)与new Object(value)两者的语义是不同的:
|
|||
|
|
|||
|
- Object(value)表示将value转成一个对象。
|
|||
|
- new Object(value)则表示新生成一个对象,它的值是value。
|
|||
|
|
|||
|
**静态方法**
|
|||
|
|
|||
|
- Object.keys():方法只返回可枚举(可遍历)的该对象自身(不是继承的)的属性数组。
|
|||
|
- Object.getOwnPropertyNames():方法返回该对象自身的属性数组(可遍历和不可遍历的都返回)。
|
|||
|
|
|||
|
```javascript
|
|||
|
var a = ['Hello', 'World'];
|
|||
|
Object.keys(a) // ["0", "1"]
|
|||
|
Object.getOwnPropertyNames(a) // ["0", "1", "length"]
|
|||
|
|
|||
|
var obj = {p1: 123,p2: 456};
|
|||
|
Object.getOwnPropertyNames(obj) // ["p1", "p2"]
|
|||
|
|
|||
|
```
|
|||
|
|
|||
|
- Object.getOwnPropertyDescriptor():获取某个属性的属性描述对象。
|
|||
|
- Object.defineProperty():通过描述对象,定义某个属性。
|
|||
|
- Object.defineProperties():通过描述对象,定义多个属性。
|
|||
|
- Object.create():该方法可以指定原型对象和属性,返回一个新的对象。
|
|||
|
- Object.getPrototypeOf():获取对象的Prototype对象。
|
|||
|
|
|||
|
|
|||
|
|
|||
|
**实例方法**
|
|||
|
|
|||
|
方法定义在Object.prototype对象,所有Object的实例对象都继承了这些方法:
|
|||
|
- Object.prototype.valueOf():返回当前对象对应的值。
|
|||
|
- Object.prototype.toString():返回当前对象对应的字符串形式。
|
|||
|
- Object.prototype.toLocaleString():返回当前对象对应的本地字符串形式。
|
|||
|
- Object.prototype.hasOwnProperty():判断某个属性是否为当前对象自身的属性,还是继承自原型对象的属性。
|
|||
|
- Object.prototype.isPrototypeOf():判断当前对象是否为另一个对象的原型。
|
|||
|
- Object.prototype.propertyIsEnumerable():判断某个属性是否可枚举。
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#### 属性描述对象
|
|||
|
|
|||
|
JavaScript 提供了一个内部数据结构,用来描述对象的属性,控制它的行为,比如该属性是否可写、可遍历等等。每个属性都有自己对应的属性描述对象,保存该属性的一些元信息。
|
|||
|
|
|||
|
Object中与对象属性相关的静态方法:
|
|||
|
|
|||
|
- `Object.getOwnPropertyDescriptor()`:获取某个属性的描述对象。
|
|||
|
- `Object.defineProperty()`:通过描述对象,定义某个属性。
|
|||
|
- `Object.defineProperties()`:通过描述对象,定义多个属性。
|
|||
|
|
|||
|
```javascript
|
|||
|
//属性描述对象
|
|||
|
{
|
|||
|
value: 123,//属性值,默认为undefined
|
|||
|
writable: false,//属性值(value)是否可改变,默认为true
|
|||
|
enumerable: true,//该属性是否可遍历,默认为true.如果设为false,for...in循环,Object.keys跳过该属性。
|
|||
|
configurable: false,//表示可配置性,默认为true
|
|||
|
get: undefined,
|
|||
|
set: undefined
|
|||
|
}
|
|||
|
|
|||
|
var obj = Object.defineProperties({}, {
|
|||
|
p1: { value: 123, enumerable: true },
|
|||
|
p2: { value: 'abc', enumerable: true },
|
|||
|
p3: {
|
|||
|
get: function () { return this.p1 + this.p2 },
|
|||
|
enumerable:true,
|
|||
|
configurable:true
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
obj.p1 // 123
|
|||
|
obj.p2 // "abc"
|
|||
|
obj.p3 // "123abc"
|
|||
|
|
|||
|
//Object.defineProperty(object, propertyName, attributesObject)
|
|||
|
var obj = Object.defineProperty({}, 'p', {
|
|||
|
value: 'abc',
|
|||
|
writable: false,//设为false,该属性不可改变
|
|||
|
enumerable: true,
|
|||
|
configurable: false
|
|||
|
});
|
|||
|
|
|||
|
obj.p // 'abc'
|
|||
|
|
|||
|
obj.p = 'ABC';
|
|||
|
obj.p // 'abc'
|
|||
|
```
|
|||
|
|
|||
|
> `Object.defineProperty()`和`Object.defineProperties()`参数里面的属性描述对象,`writable`、`configurable`、`enumerable`这三个属性的默认值都为`false
|
|||
|
|
|||
|
Object中与对象状态有关的静态方法:
|
|||
|
|
|||
|
- `Object.preventExtensions()`:防止对象扩展,使得对象无法再添加新的属性。
|
|||
|
- `Object.isExtensible()`:判断对象是否可扩展。
|
|||
|
- `Object.seal()`:禁止对象配置,使得对象无法添加新的属性,也不能删除旧的属性。
|
|||
|
- `Object.isSealed()`:判断一个对象是否可配置。
|
|||
|
- `Object.freeze()`:冻结一个对象,使得一个对象无法添加新属性、无法删除旧属性、也无法改变属性的值,使得这个对象实际上变成了常量。
|
|||
|
- `Object.isFrozen()`:判断一个对象是否被冻结。
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#### JSON对象
|
|||
|
|
|||
|
`JSON`对象是 JavaScript 的原生对象,用来处理 JSON 格式数据(大括号加键值对的形式)。
|
|||
|
|
|||
|
拥有两个静态方法:
|
|||
|
|
|||
|
- JSON.stringify方法用于将一个值转为串符合 JSON 格式的字符串;
|
|||
|
- JSON.parse方法用于将 JSON 字符串转换成对应的值。
|
|||
|
|
|||
|
通过var obj = new Object()的写法生成新对象,与字面量的写法var obj = {}是等价的。
|
|||
|
|
|||
|
```javascript
|
|||
|
var obj = { "p": 1 };
|
|||
|
'p' in obj // true
|
|||
|
```
|
|||
|
|
|||
|
|
|||
|
> in运算符用于检查对象是否包含某个属性,它不能识别哪些属性是对象自身的,哪些属性是继承的,通常与Object的实例方法hasOwnProperty()搭配使用
|
|||
|
|
|||
|
Object(value)与new Object(value)两者的语义是不同的:
|
|||
|
|
|||
|
- Object(value)表示将value转成一个对象;
|
|||
|
- new Object(value)则表示新生成一个对象,它的值是value。
|
|||
|
|
|||
|
对于JSON对象,建议key值用单引号,数字键可以不加因为会自动转为字符串类型但不能用点运算符。
|
|||
|
|
|||
|
JSON 对值的类型和格式有严格的规定。
|
|||
|
|
|||
|
1. 复合类型的值只能是数组或对象,不能是函数、正则表达式对象、日期对象。
|
|||
|
2. 原始类型的值只有四种:字符串、数值(必须以十进制表示)、布尔值和null(不能使用NaN, Infinity, -Infinity和undefined)。
|
|||
|
3. 字符串必须使用双引号表示,不能使用单引号。
|
|||
|
4. 对象的键名必须放在双引号里面。
|
|||
|
5. 数组或对象最后一个成员的后面,不能加逗号。
|
|||
|
|
|||
|
**遍历JSON对象**
|
|||
|
|
|||
|
```javascript
|
|||
|
var person = { "name": "张三","age": 18 ,"stature": 180};
|
|||
|
//for..in会遍历对象所有可遍历(enumerable)的属性,会跳过不可遍历的属性。
|
|||
|
for (var key in person) {
|
|||
|
if (person.hasOwnProperty(key)) {
|
|||
|
console.log(key);
|
|||
|
}
|
|||
|
}
|
|||
|
//取json对象的方式
|
|||
|
person.name
|
|||
|
person["age"]
|
|||
|
```
|
|||
|
|
|||
|
|
|||
|
|
|||
|
### 参考文章
|
|||
|
|
|||
|
[1] Object对象 `https://wangdoc.com/javascript/stdlib/object.html`
|
|||
|
|
|||
|
[2] 属性描述对象] `https://wangdoc.com/javascript/stdlib/attributes.html`
|
|||
|
|
|||
|
[3] 标准库-JSON对象 `https://javascript.ruanyifeng.com/stdlib/json.html`
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|