变量类型和计算

typeof能判断哪些类型

  • undefind string number boolean symbol
  • object (.typeof null === ‘object’ )
  • function

识别所有值类型

  1. let a0;
  2. console.log(typeof a0); // undefined
  3. const a1 = "string";
  4. console.log(typeof a1); // string
  5. const a2 = 1;
  6. console.log(typeof a2); // number
  7. const a3 = true;
  8. console.log(typeof a3); // boolean
  9. const a4 = Symbol("a4");
  10. console.log(typeof a4); // symbol

识别函数

  1. console.log(typeof console.log); // function
  2. console.log(typeof (() => {})); // function

判断是否是引用类型(不可在细分)

如需判断是否是数组,对象等,请用 instanceof

  1. const a0 = null;
  2. console.log(typeof a0); //object
  3. const a1 = { name: "wcd" };
  4. console.log(typeof a1); // object
  5. const a2 = ["a"];
  6. console.log(typeof a2); // object

类型转化

强制类型转换:paresInt, ParseFloat, toString… 隐式类型转换:if, 逻辑运算,== ,拼接字符串

String or toString

String() or toString() 都是将其他类型的变量转换为字符串类型 toString() 无法转换 null 和 undefined

  1. let a;
  2. let b = null;
  3. // console.log(a.toString()); // Cannot read property 'toString' of undefined
  4. // console.log(b.toString()); // Cannot read property 'toString' of null
  5. console.log(String(a)); // undefined
  6. console.log(String(b)); // null

变量计算

字符串拼接

  1. console.log(100 + 10); // 110
  2. console.log(100 + "10"); // '10010'
  3. console.log(true + "10"); // 'true10'

== 运算符

  1. console.log(100 == "100"); // true
  2. console.log(0 == ""); // true
  3. console.log(0 == false); // true
  4. console.log(false == ""); // true
  5. console.log(null == undefined); // true
  6. /**
  7. * TODO: 偷懒写法,除 xx == null 之外,一律采用 ===
  8. * 其实jQuery与代码打包之后也是这样的形式,
  9. */
  10. const obj = {
  11. name: "wcd",
  12. };
  13. if (obj.age == null) {
  14. // ...
  15. }
  16. // 相当于
  17. if (obj.age === null || obj.age === undefined) {
  18. // ...
  19. }

if 语句与逻辑运算

  1. // 经过两次非运算为 true 的为 truly 变量,反之则为 falsely
  2. // truly 变量: !!a === true
  3. // falsely 变量: !!a === false
  4. const num = 100;
  5. console.log(!num); // false
  6. console.log(!!num); // true
  7. console.log(!!{}); // true
  8. // 除此之外都是truly变量
  9. console.log(!!0); // false
  10. console.log(!!NaN); // false
  11. console.log(!!""); // false
  12. console.log(!!null); // false
  13. console.log(!!undefined); // false
  14. console.log(!!false); // false

逻辑判断

  1. console.log(10 && 0); // 0
  2. console.log("" || "abc"); // 'abc'
  3. // TODO: window环境下测试
  4. console.log(!window.abc); // true

原型和原型链

class 与 继承

类与继承

class的原型本质

  1. class Parent {
  2. constructor(name = "wcd") {
  3. this.name = name;
  4. }
  5. }
  6. class Child extends Parent {}
  7. console.log(new Child());
  8. console.log(typeof Parent); // function
  9. console.log(typeof Child); // function
  10. // class的类型实际上是函数,所有可见class是语法糖

类型判断 instanceof

instanceof 与 typeof

instanceof 与 typeof 相比,instanceof 方法要求开发者明确的确认对象为某特定类型。 即 instanceof 用于判断引用类型属于哪个构造函数的方法。

  1. const arr = [];
  2. console.log(arr instanceof Array); // true
  3. console.log(typeof arr); // "object"

继承关系

instanceof 操作符用于检测对象是否属于某个 class,同时,检测过程中也会将继承关系考虑在内。

  1. // 类
  2. class Parent {}
  3. const _Parent = new Parent();
  4. console.log(_Parent instanceof Parent); // true
  5. // 也可以是构造函数,而非 class
  6. function GeParent() {}
  7. const ge = new GeParent();
  8. console.log(ge instanceof GeParent); // true

另外,更重的一点是 instanceof 可以在继承关系中用来判断一个实例是否属于它的父类型。

  1. // 判断 f1 是否是 Fn 类的实例 , 并且是否是其父类型的实例
  2. function An() {}
  3. function Fn() {}
  4. Fn.prototype = new An();
  5. var f1 = new Fn();
  6. console.log(f1 instanceof Fn); // true
  7. console.log(f1 instanceof An); // true

f1 instanceof Fn 的判断逻辑是:

  • f1 的 _proto_ 一层一层往上,是否对应到 Fn.prototype
  • 再往上,看是否对应着 An.prototype
  • 再试着判断 f1 instanceof Object

原型和原型链

作用域和闭包

  1. // 闭包作用
  2. {
  3. // 闭包隐藏数据,只提供 API
  4. function createCache() {
  5. const data = {}; // 闭包中的数据,被隐藏,不被外界访问
  6. return {
  7. set: function (key, val) {
  8. data[key] = val;
  9. },
  10. get: function (key) {
  11. return data[key];
  12. },
  13. };
  14. }
  15. const c = createCache();
  16. c.set("a", 100);
  17. console.log(c.get("a"));
  18. }

this

  1. // 模拟 bind
  2. Function.prototype.bind1 = function () {
  3. // 将参数拆解为数组
  4. const args = Array.prototype.slice.call(arguments)
  5. // 获取 this(数组第一项)
  6. const t = args.shift()
  7. // fn1.bind(...) 中的 fn1
  8. const self = this
  9. // 返回一个函数
  10. return function () {
  11. return self.apply(t, args)
  12. }
  13. }
  14. function fn1(a, b, c) {
  15. console.log('this', this)
  16. console.log(a, b, c)
  17. return 'this is fn1'
  18. }
  19. const fn2 = fn1.bind1({x: 100}, 10, 20, 30)
  20. const res = fn2()
  21. console.log(res)

写 var 与不写 var 有什么区别

  1. // 思考:写 var 与不写 var 有什么区别
  2. // 使用 var 关键字定义变量的时候,相当于在当前的作用域内声明了一个变量
  3. // varFun函数声明 a1 变量,a1 相当于局部变量,只允许当前作用域内访问
  4. // 如果不使用 var 相当于属性的赋值,相当于在window全局定义属性b
  5. // delete 操作符用于删除对象的某个属性;如果没有指向这个属性的引用,那它最终会被释放。
  6. // TODO: 可以验证变量跟属性
  7. // var variable
  8. var a = 1;
  9. console.log(a); // 1
  10. delete a;
  11. console.log(a); // 1
  12. b = 2;
  13. console.log(b); // 2
  14. delete b;
  15. console.log(b); // b is not defined
  16. (function varFun() {
  17. var c = 3;
  18. console.log(c); // 3
  19. })();
  20. console.log(c); // c is not defined

闭包题目

  1. function fun(n, o) {
  2. console.log(o);
  3. return {
  4. fun: function (m) {
  5. return fun(m, n);
  6. },
  7. };
  8. }
  9. var a = fun(0); a.fun(1); a.fun(2); a.fun(3); // undefined,0,0,0
  10. var b = fun(0).fun(1).fun(2).fun(3); // undefined,0,1,2
  11. var c = fun(0).fun(1); // undefined,0

解答:https://www.cnblogs.com/xxcanghai/p/4991870.html

参考

JavaScript instanceof 运算符深入剖析