JS基础知识系统整理(不断更新)


一、基础知识

1.变量类型

  • JS中使用typeof 能得到哪些类型
  • 何时使用 === 何时使用 ==
  • JS中有哪些内置函数
  • JS变量按照存储方式区分为哪些类型,并描述其特点
  • 如何理解JSON

值类型:

每个变量存储各自的值,不会相互影响,number , string , boolean 

var a = 100;
var b = a;
a = 200;
console.log(b);    //100

引用类型:

变量只是通过一个指针指向对象,改变了age对象,由于a也指向该对象,所以a指向的age对象为21, object , array , function

var a = {age:20}
var b = a
b.age = 21
console.log(a.age)    //21

typeof 运算符

有六种类型:undefined , string , number , boolean , object , function ; typeof只能区分值类型的详细类型;

typeof {}    //object
typeof []    //object
typeof null    //object
typeof console.log    //function

2.变量计算 - 强制类型转换

字符串拼接

var a = 100 + 10    //110
var b = 100 + '10'    //10010

==运算符

obj.a == null ——> obj.a === null || obj.a === undefined

(除了 obj.a == null 用== 其余都用=== ,jQuery 源码推荐写法)

100 == ‘100’    //true
0 == ''    //true
null == undefined    //true

if语句

var a = true
if(a){//...}

var b = 100
if(b){//...}

var c = ''
if(c){//...}

if中转换为false的情况:

if(0){}
if(NaN){}
if(''){}
if(null){}
if(false){}

逻辑运算符

console.log(10 && 0)    //0
console.log('' || 'abc')    //'abc'
console.log(!window.abc)    //true  因为window.abc 是undefined

判断一个变量会被当作true还是false

var a = 100;
console.log(!!a) 

JS中的内置函数

Object , Array , Boolean , Number , String , Function , Date , RegExp , Error

(注意:Math 是对象,不是函数)

理解JSON

//JSON 是 JS 一个内置对象而已

JSON.stringify({a:10, b:20})   对象转换字符串

JSON.parse('{"a":10, "b":20}')  字符串转换成对象

3.原型和原型链

  • 如何准确判断变量是数组类型
  • 写一个原型链继承的例子
  • 描述new 一个对象的过程
  • zepto源码中如何使用原型链

构造函数

function Foo(name, age){
    this.name = name;
    this.age = age;
    this.class = 'class-1'
    //return this  //默认有这一行
}

var f = new Foo('zhangsan',20)
// var f1 = new Foo('lisi',22)    //可创建多个对象

开头字母须大写

new Foo()时把参数传进去,this会先变成空对象,挨个赋值之后,会return出来给f,

f就具备了调用属性的能力。

构造函数扩展

  • var a = {} 其实是 var a = new Object() 的语法糖
  • var a = [] 其实是 var a = new Array()的语法糖
  • function Foo(){...} 其实是 var Foo = new Function(...)
  • 使用instanceof 判断一个函数是否是一个变量的构造函数(判断一个变量是否为“数组”: 变量 instanceof Array)

原型规则和示例

  • 所有的引用类型(数组、对象、函数),都具有对象特性,即可自由扩展属性(除了“null” 以外)
  • //自由扩展属性
    var obj = {}; obj.a = 100;
    var arr = []; arr.a = 100;
    function fn (){}
    fn.a = 100;
  • 所有的引用类型(数组、对象、函数),都有一个 __proto__属性(隐式原型),属性值是一个普通对象
    console.log(obj.__proto__);    //Object
    console.log(arr.__proto__);    //Array[0]
    console.log(fn.__proto__);    //function(){}
  • 所有的函数,都有一个prototype属性(显式原型),属性值也是一个普通的对象
    console.log(fn.prototype);    //Object{}
  • 所有的引用类型(数组、对象、函数),__proto__属性值指向它的构造函数的"prototype"属性值,(指向和完全等是一个概念)
    console.log(obj.__proto__ === Object.prototype);    //true
    • 当试图得到一个引用类型值的某个属性时,如果这个对象本身没有这个属性,那么会去它的__proto__(即它的构造函数的prototype)中寻找。
      function Foo(name,age){
          this.name = name;
      }
      Foo.prototype.altername = function(){
          alert(this.name);
      }
      
      var f = new Foo('zhangsan');
      f.printname = function(){
          console.log(this.name);
      }
      
      f.printname();
      f.altername();
      f.toString();  //要去 f.__proto__.__proto__中查找

 循环对象自身的属性:

var item;
for(item in f){
    //高级浏览器已经在 for in 中屏蔽了来自原型的属性
    //但是这里建议大家还是加上这个判断,保证程序的健壮性
    if(f.hasOwnProperty(item)){
        console.log(item);
    }
}

原型链:

instanceof

判断引用类型 属于哪个构造函数的方法

比如 f instanceof Foo 的判断逻辑是:

f 的 __proto__ 一层一层往上,能否对应到Foo.prototype,再试着判断 f instanceof Object

原型链继承的例子

基本:

//动物
function Animal(){
    this.eat = function(){
        console.log('animal eat');
    }
}
//
function Dog(){
    this.bark = function(){
        console.log('dog bark');
    }
}

Dog.prototype = new Animal();
var hashiqi = new Dog();

实例:

function Elem(id){
    this.elem = document.getElementById(id);
}

Elem.prototype.html = function(val){
    var elem = this.elem;
    if(val){
        elem.innerHTML = val;
        return this;    //链式操作
    }else{
        return elem.innerHTML;
    }
}

Elem.prototype.on = function(type,fn){
    var elem = this.elem;
    elem.addEventListener(type,fn);
}

var div1 = new Elem('div1');

div1.html('

hello world

').on('click', function(){ alert('clicked'); })

描述new一个对象的过程

  1. 创建一个新对象
  2. this 指向这个新对象
  3. 执行代码,即对 this 赋值
  4. 返回 this

4、作用域和闭包

执行上下文

在执行代码前,先把定义声明获取一遍,再由上到下执行

  • 范围:一段