meface/docs/article/web/index.md

314 lines
10 KiB
Markdown
Raw Normal View History

2023-11-17 10:54:23 +08:00
---
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`