10 KiB
JavaScript 基础
变量和数据类型
JavaScript 的变量名区分大小写,A和a是两个不同的变量。声明变量的标识符不能以数字开头,字符集为Unicode。如果一个变量只是声明而没有被赋值,则该变量的值为underfined。
所有的数据都是用var定义。
var name = "admin";
var age = 26;
var obj = new Date();
如果使用var声明一个已经存在的变量,是无效的,但如果并进行了赋值,则会覆盖掉前面的值
ES6中新增了let、const 定义变量
变量提升
JavaScript 引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的【声明语句】(var a;),都会被提升到代码的头部,这就叫做变量提升(hoisting)
区块(block)
{
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元运算符,返回跟在其后面变量的数据类型的字符串。
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。
Number(null) // 0
Number(undefined) // NaN
parseInt逐个解析字符,而Number函数整体转换字符串的类型
返回undefined的典型场景:
- 变量声明了,但没有赋值
- 调用函数时,应该提供的参数没有提供,该参数等于 undefined
- 对象没有赋值的属性
- 函数没有返回值时,默认返回 undefined
隐式布尔型:
当预期某个位置应该是布尔值,会将该位置上现有的值自动转为布尔值
- "": false,对于任何非空字符串都是 true.
- 0: false,对于任何非0数值都是 true.
- null: false,对于任何非空对象都是 true.
对象
Object对象
其他对象指的是调用对象的toString()方法返回"[object Object]"的对象。第二个Object是该对象创建时使用的构造函数,可以是Number、String、Boolean、Undefined、Null、Array、Arguments、Function、Error、Date、RegExp、Object。
本身方法:直接定义在Object对象上的方法。
实例方法:定义在Object原型对象Object.prototype上的方法。
在Object.prototype对象上面的属性和方法,将被所有实例对象共享。
构造函数与Object()
作为构造函数使用new关键字创建新的对象。
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():方法返回该对象自身的属性数组(可遍历和不可遍历的都返回)。
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()
:通过描述对象,定义多个属性。
//属性描述对象
{
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 = {}是等价的。
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 对值的类型和格式有严格的规定。
- 复合类型的值只能是数组或对象,不能是函数、正则表达式对象、日期对象。
- 原始类型的值只有四种:字符串、数值(必须以十进制表示)、布尔值和null(不能使用NaN, Infinity, -Infinity和undefined)。
- 字符串必须使用双引号表示,不能使用单引号。
- 对象的键名必须放在双引号里面。
- 数组或对象最后一个成员的后面,不能加逗号。
遍历JSON对象
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