作用域(scope)
全局作用域
- 直接编写在
<script>
标签中的JS代码,都在全局作用域 - 全局作用域在页面(html)打开时创建,在页面(html)关闭时销毁
- 全局作用域中有一个全局对象
window
window
代表的是一个浏览器的窗口。window
由浏览器创建,提供给我们使用
- 在全局作用域中
- 创建的变量都会作为
window
对象的属性 - 创建的函数都会作为
window
对象的方法 - 这些 变量 和 函数 在页面(html)的任何一个
js文件/<script>
中都可以访问到
- 创建的变量都会作为
- 可以说是一个html,一个全局作用域
var a = 456;
function b() {}
console.log(window.a); // 456
console.log(window.b); // function b() {}
函数作用域
- 在某个函数A中,声明的变量/函数,都在这个A函数的作用域中
- 这些 变量 和 函数 在该A函数中可以访问到
- 在A函数外就访问不到 ```javascript function fn() { var a = 5; console.log(a); // 5 }
console.log(a); // undefined
<a name="oK5Ws"></a>
# 字符集
<a name="FsP4W"></a>
## 概念
- 字符:character
- 字符集:character set
- 指某一类字符的集合,包括英文字母,符号,数字,汉字,标点等等
- 常见的字符集:ASCII、ISO/IEC 646、Unicode、GB2312
- 码点:code point
- 编码字符集:coded character set
- 编码字符集内的 每一个字符 都有一个独特的数字对应,这个数字被称为码点code point。码点是字符在字符集中的编号
- 编码:encoding
- 码点到字节的映射
- 指一种机制,将码点映射到某几个字节bytes,使得字符在不同的系统能够用同一套编码模式来进行统一表示
- 如:ASCII、UTF-8/UTF-16/UTF-32(Unicode编码方式)
- _ASCII,GB2312本身既指一种字符集,也是一种编码,因为早期字符集和编码是绑定的,是一整套方案。_
<a name="YJ1v7"></a>
## 字符集的类型
- **ASCII码**:美国信息交换标准编码
- **Unicode码:**统一码,也叫万国码、单一码是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的[二进制编码](https://baike.baidu.com/item/%E4%BA%8C%E8%BF%9B%E5%88%B6%E7%BC%96%E7%A0%81/1758517),以满足跨语言、跨平台进行文本转换、处理的要求
- `Unicode字符集`的学名:Universal Multiple-Octet Coded Character Set,简称为UCS
- 现在用的是UCS-2,即2个字节编码,而UCS-4是为了防止将来2个字节不够用才开发的
<a name="c7nyf"></a>
## JS的字符集
- JavaScript 使用 Unicode 字符集。JavaScript 引擎内部,所有字符都用 Unicode 表示。
- JavaScript 不仅以 Unicode 储存字符,还允许直接在程序中使用 Unicode 码点表示字符,即将字符写成`\uxxxx`的形式,其中`xxxx`代表该字符的 Unicode 码点。
- 比如,`\u00A9`代表版权符号
- ES5中,`\uxxxx`中x必须是4个,才能显示,这也就限制了字符的数量。
- ES6就改进了,解决了这个问题
```javascript
var str = '\u00A9'
console.log(str); // ©
var f\u006F\u006F = 'abc'; // 用Unicode 形式表示 foo
// 等价于这么写,let foo = 'abc'; 用字面形式表示 foo
console.log(foo);
var str = '456';
/**
* 由于ES5只有将Unicode编码 转成 字符串的函数,需要自己实现一个函数
* 将字符串转成Unicode编码的数组
* @param {String} str
* @returns number[]
*/
String.fromStrToCharCode = function (str) {
var res = [];
for (var i = 0; i < str.length; i++) {
res.push(str[i].charCodeAt(0));
}
return res;
}
var charCode = String.fromStrToCharCode(str);
// String.fromCharCode()不能识别大于0xFFFF的码点,所以0x20BB7就发生了溢出,最高位2被舍弃了
// ES6 提供了String.fromCodePoint()方法,可以识别大于0xFFFF的字符,弥补了String.fromCharCode()方法的不足。
var str2 = String.fromCharCode.apply(this, charCode)
六种数据类型
- undefined
- null
- boolean
- string
- number
- object
Object对象
ECMA-262 把对象定义为:无序属性的集合,其属性值 可以是 基本值、对象或者函数
- 我们可以把对象想象成散列表:无非就是一组键值对,其中值可以是数据或函数
- 这里讨论的对象是满足如下的等式的变量
(variate)
Object.prototype.toString.call(**variate**).slice(8, -1) === 'Object'
对象的属性可以理解为:值为数据的 键值对 ```javascript // 案例一:给对象设置属性:数据属性和访问器属性 // 添加数据属性(简易方式) var obj = { name: ‘Jack’, age: 18, _visit: 0, // 这个变量,帮助我们下面构造访问器函数。这个变量可以不用放在obj对象上 }
// obj有三个数据属性 obj.name // ‘Jack’ obj.age // 18 obj._visit // 0
// 添加访问器属性 Object.defineProperty(obj, “visit”, { get: function () { // 访问一次,自增一次 return ++this._visit; }, set: function (val) { this._visit = val; } })
console.log(obj._visit, obj.visit, obj._visit); // 0 1 1
obj.visit = 100; console.log(obj._visit, obj.visit, obj._visit); // 100 101 101
- 对象的方法可以理解为:值为 函数的 键值对
```javascript
// 案例二;对象的方法
var obj = {
say: function() {
console.log('say')
},
}
对象的属性类型
- ES5中, 有两种属性类型:数据属性和访问器属性
- 数据属性包含哪些特性
(attribute)
[[Configurable]]
: 表示能否通过 delete 删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。默认值true
[[Enumerable]]
: 表示能否通过 for-in 循环返回属性。默认值为true
[[Writable]]
: 表示能否修改属性的值。默认值true
[[Value]]
: 包含这个属性的数据值。读取属性值的时候,从这个位置读;写入属性值的时候, 把新值保存在这个位置。默认值undefined
- 访问器属性包含哪些特性
(attribute)
[[Configurable]]
:表示能否通过 delete 删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。默认值true
[[Enumerable]]
:表示能否通过 for-in 循环返回属性。默认值为true
[[Get]]
: 在读取属性时调用的函数。默认值为undefined
[[Set]]
: 在写入属性时调用的函数。默认值为undefined
- 如何定义这些特性
Object.defineProperty(variate, key, attribute)
Object.defineProperties(variate, { key1: attribute1, key2: attribute2 })
- 没有明确用这些方法定义特性,属性的特性都采用默认值
- 如何获取某个属性的特性
Object.getOwnPropertyDescriptor(obj, key)
: 返回值是一个对象,如果是访问器属性,这个对象的属性有configurable、enumerable、get、set
。如果是数据属性,这个对象的属性有configurable、enumerable、writable、value
```javascript // 定义数据属性的特性 var obj = {};
- 数据属性包含哪些特性
Object.defineProperty(obj, ‘name’, { configurable: false, enumerable: true, writable: true, value: ‘good’ })
console.log(obj.name); // good delete obj.name; // 由于该属性的configurable为false,删不掉,所以下一行的还是good console.log(obj.name); // good
// 值得注意的一点:没有设置configurable、enumerable、writable,自动设置为false Object.defineProperty(obj, ‘age’, { value: 18 })
delete obj.age; console.log(obj.age); // 18 obj.age = 20 console.log(obj.age); // 18
```javascript
// 定义访问器属性的特性
// set和get可以不用同时设置
var obj = {}
var _visit = 0;
Object.defineProperty(obj, 'visit', {
configurable: true,
enumerable: true,
get: function () {
// 每次访问,自增
return ++_visit;
}
})
console.log(obj.visit) // 1
console.log(obj.visit) // 2
console.log(obj.visit) // 3
delete obj.visit
console.log(obj.visit) // undefined