作用域(scope)
全局作用域
- 直接编写在
<script>标签中的JS代码,都在全局作用域 - 全局作用域在页面(html)打开时创建,在页面(html)关闭时销毁
- 全局作用域中有一个全局对象
windowwindow代表的是一个浏览器的窗口。window由浏览器创建,提供给我们使用
- 在全局作用域中
- 创建的变量都会作为
window对象的属性 - 创建的函数都会作为
window对象的方法 - 这些 变量 和 函数 在页面(html)的任何一个
js文件/<script>中都可以访问到
- 创建的变量都会作为
- 可以说是一个html,一个全局作用域
var a = 456;function b() {}console.log(window.a); // 456console.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就改进了,解决了这个问题```javascriptvar str = '\u00A9'console.log(str); // ©
var f\u006F\u006F = 'abc'; // 用Unicode 形式表示 foo// 等价于这么写,let foo = 'abc'; 用字面形式表示 fooconsole.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) // 1console.log(obj.visit) // 2console.log(obj.visit) // 3delete obj.visitconsole.log(obj.visit) // undefined
