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__中查找
- 当试图得到一个引用类型值的某个属性时,如果这个对象本身没有这个属性,那么会去它的__proto__(即它的构造函数的prototype)中寻找。
循环对象自身的属性:
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一个对象的过程
- 创建一个新对象
- this 指向这个新对象
- 执行代码,即对 this 赋值
- 返回 this
4、作用域和闭包
- 说一下对变量提升的理解
- 说明this几种不同的使用场景
- 创建 10 个标签,点击的时候弹出来对应的序号
- 如何理解作用域
- 实际开发中闭包的应用
执行上下文
在执行代码前,先把定义声明获取一遍,再由上到下执行
- 范围:一段