作用域(scope)

全局作用域

  • 直接编写在<script>标签中的JS代码,都在全局作用域
  • 全局作用域在页面(html)打开时创建,在页面(html)关闭时销毁
  • 全局作用域中有一个全局对象window
    • window代表的是一个浏览器的窗口。window由浏览器创建,提供给我们使用
  • 在全局作用域中
    • 创建的变量都会作为window对象的属性
    • 创建的函数都会作为window对象的方法
    • 这些 变量 和 函数 在页面(html)的任何一个js文件/<script>中都可以访问到
  • 可以说是一个html,一个全局作用域
  1. var a = 456;
  2. function b() {}
  3. console.log(window.a); // 456
  4. console.log(window.b); // function b() {}

函数作用域

  • 在某个函数A中,声明的变量/函数,都在这个A函数的作用域中
    • 这些 变量 和 函数 在该A函数中可以访问到
    • 在A函数外就访问不到 ```javascript function fn() { var a = 5; console.log(a); // 5 }

console.log(a); // undefined

  1. <a name="oK5Ws"></a>
  2. # 字符集
  3. <a name="FsP4W"></a>
  4. ## 概念
  5. - 字符:character
  6. - 字符集:character set
  7. - 指某一类字符的集合,包括英文字母,符号,数字,汉字,标点等等
  8. - 常见的字符集:ASCII、ISO/IEC 646、Unicode、GB2312
  9. - 码点:code point
  10. - 编码字符集:coded character set
  11. - 编码字符集内的 每一个字符 都有一个独特的数字对应,这个数字被称为码点code point。码点是字符在字符集中的编号
  12. - 编码:encoding
  13. - 码点到字节的映射
  14. - 指一种机制,将码点映射到某几个字节bytes,使得字符在不同的系统能够用同一套编码模式来进行统一表示
  15. - 如:ASCII、UTF-8/UTF-16/UTF-32(Unicode编码方式)
  16. - _ASCII,GB2312本身既指一种字符集,也是一种编码,因为早期字符集和编码是绑定的,是一整套方案。_
  17. <a name="YJ1v7"></a>
  18. ## 字符集的类型
  19. - **ASCII码**:美国信息交换标准编码
  20. - **Unicode码:**统一码,也叫万国码、单一码是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的[二进制编码](https://baike.baidu.com/item/%E4%BA%8C%E8%BF%9B%E5%88%B6%E7%BC%96%E7%A0%81/1758517),以满足跨语言、跨平台进行文本转换、处理的要求
  21. - `Unicode字符集`的学名:Universal Multiple-Octet Coded Character Set,简称为UCS
  22. - 现在用的是UCS-2,即2个字节编码,而UCS-4是为了防止将来2个字节不够用才开发的
  23. <a name="c7nyf"></a>
  24. ## JS的字符集
  25. - JavaScript 使用 Unicode 字符集。JavaScript 引擎内部,所有字符都用 Unicode 表示。
  26. - JavaScript 不仅以 Unicode 储存字符,还允许直接在程序中使用 Unicode 码点表示字符,即将字符写成`\uxxxx`的形式,其中`xxxx`代表该字符的 Unicode 码点。
  27. - 比如,`\u00A9`代表版权符号
  28. - ES5中,`\uxxxx`中x必须是4个,才能显示,这也就限制了字符的数量。
  29. - ES6就改进了,解决了这个问题
  30. ```javascript
  31. var str = '\u00A9'
  32. console.log(str); // ©
  1. var f\u006F\u006F = 'abc'; // 用Unicode 形式表示 foo
  2. // 等价于这么写,let foo = 'abc'; 用字面形式表示 foo
  3. console.log(foo);
  1. var str = '456';
  2. /**
  3. * 由于ES5只有将Unicode编码 转成 字符串的函数,需要自己实现一个函数
  4. * 将字符串转成Unicode编码的数组
  5. * @param {String} str
  6. * @returns number[]
  7. */
  8. String.fromStrToCharCode = function (str) {
  9. var res = [];
  10. for (var i = 0; i < str.length; i++) {
  11. res.push(str[i].charCodeAt(0));
  12. }
  13. return res;
  14. }
  15. var charCode = String.fromStrToCharCode(str);
  16. // String.fromCharCode()不能识别大于0xFFFF的码点,所以0x20BB7就发生了溢出,最高位2被舍弃了
  17. // ES6 提供了String.fromCodePoint()方法,可以识别大于0xFFFF的字符,弥补了String.fromCharCode()方法的不足。
  18. 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

  1. - 对象的方法可以理解为:值为 函数的 键值对
  2. ```javascript
  3. // 案例二;对象的方法
  4. var obj = {
  5. say: function() {
  6. console.log('say')
  7. },
  8. }

对象的属性类型

  • 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

  1. ```javascript
  2. // 定义访问器属性的特性
  3. // set和get可以不用同时设置
  4. var obj = {}
  5. var _visit = 0;
  6. Object.defineProperty(obj, 'visit', {
  7. configurable: true,
  8. enumerable: true,
  9. get: function () {
  10. // 每次访问,自增
  11. return ++_visit;
  12. }
  13. })
  14. console.log(obj.visit) // 1
  15. console.log(obj.visit) // 2
  16. console.log(obj.visit) // 3
  17. delete obj.visit
  18. console.log(obj.visit) // undefined