//值类型 var a=100 var b=a a=200 console.log(b) //100 //引用类型 var a={age:20} var b=a b.age=21 console.log(a.age) //21
// Numbers typeof 37 === 'number'; typeof 3.14 === 'number'; typeof Math.LN2 === 'number'; typeof Infinity === 'number'; typeof NaN === 'number'; // 尽管NaN是"Not-A-Number"的缩写 typeof Number(1) === 'number'; // 但不要使用这种形式! // Strings typeof "" === 'string'; typeof "bla" === 'string'; typeof (typeof 1) === 'string'; // typeof老是返回一个字符串 typeof String("abc") === 'string'; // 但不要使用这种形式! // Booleans typeof true === 'boolean'; typeof false === 'boolean'; typeof Boolean(true) === 'boolean'; // 但不要使用这种形式! // Symbols typeof Symbol() === 'symbol'; typeof Symbol('foo') === 'symbol'; typeof Symbol.iterator === 'symbol'; // Undefined typeof undefined === 'undefined'; typeof declaredButUndefinedVariable === 'undefined'; typeof undeclaredVariable === 'undefined'; // Objects typeof {a:1} === 'object'; // 使用Array.isArray 或者 Object.prototype.toString.call // 区分数组,普通对象 typeof [1, 2, 4] === 'object'; typeof new Date() === 'object'; // 下面的容易使人迷惑,不要使用! typeof new Boolean(true) === 'object'; typeof new Number(1) ==== 'object'; typeof new String("abc") === 'object'; // 函数 typeof function(){} === 'function'; typeof Math.sin === 'function'; //NaN typeof 1/0 === 'NaN'; //null typeof null === 'object';
//逻辑运算符 console.log(10 & 0) //0 转换为true&&0 console.log(''||'abc') //abc 转换为false||'abc' console.log(!window.abc) //true !undefined为true //if语句 false状况 null '' false 0 NaN undefined //判断一个变量是否看成true或者false var a = 100 console.log(!!a)
1.JS中使用typeof能获得哪些类型
undefined null string number object function boolean symbol
2.什么时候使用'===',什么时候使用'=='
参考jQuery源码 只有这种状况下使用'==':javascript
if(obj.a == null) { } //这句至关于obj.a === null || obj.a === undefined
3.JS有哪些内置函数
Object Array String Number Function Boolean Date RegExp Error
4.JS变量按照存储方式分为哪些类型,并描述其特色
值类型、引用类型。
值类型是将变量的值存在内存中。
引用类型的变量是真实变量的指针(对象、数组、函数)。能够无限扩张属性。
5.如何理解JSON
是JavaScript的对象,内置两个方法 JSON.stringify JSON.parsehtml
function Foo(name, age) { this.name = name this.age = age this.class = 'class-1' //return this 默认有这行 } var f = new Foo('zs', 20) //执行过程:1.new函数执行时this会变成空对象 2.this. 的时候赋值 3.return this 4.给f赋值 //var a = {} ===> var a = new Object() //var a =[] ===> var a = new Array() //function Foo(){} ===> var Foo = new Function() //instanceof 用于判断一个函数是不是一个变量的构造函数
//全部的引用类型(数组、对象、函数)都具备对象特性,除了null以外,均可以自由扩展属性 //全部的引用类型 都有__proto__ 隐式原型 //全部的函数都有 prototype 显式原型 属性值也是一个普通对象 //全部的引用类型(数组、对象、函数),__proto__属性值指向它的构造函数的prototype属性值 var obj = {}; obj.a = 100 var arr = []; arr.a = 100 function fn () {} fn.a = 100 console.log(obj.__proto__) console.log(arr.__proto__) console.log(fn.__proto__) console.log(fn.prototype) console.log(obj.__proto__ === Object.prototype) //试图获得一个对象的某个属性时,若是这个对象自己没有这个属性,那么会去它的__proto__(构造函数的prototype)中寻找 function Foo(name, age) { this.name = name } Foo.prototype.alertName = function () { alert(this.name) } var f = new Foo('zs') f.printName = function () { console.log(this.name) } f.printName() f.alertName()
//instanceof 是用于判断引用类型属于哪一个构造函数的方法 //构造函数 function Foo(name, age) { this.name = name } Foo.prototype.alertName = function () { alert(this.name) } //建立实例 var f = new Foo('zs') f.printName = function () { console.log(this.name) } f.printName() f.alertName() f.toString() // f instanceof Foo 判断过程: // f 的 __proto__一层层往上找到是否对应Foo.prototype // 再判断f instanceof Object
直角矩形是构造函数 圆角矩形是对象java
var obj={ x:100, y:200, z:300 } var key for(key in obj){ //hasOwnProperty会返回一个布尔值,判断是不是原生的属性,以此来排除原型链上的属性 if(obj.hasOwnProperty(key)){ console.log(key,obj[key]); } } //x 100 //y 200 //z 300
6.如何准确判断一个变量是数组函数面试
var arr = [] arr instanceof Array typeof arr //object, typeof 是没法判断是不是数组的
7.写一个原型链继承的例子数组
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) return this } var div1 = new Elem('wrapper') div1.html('<p>hello</p>').on('click', function () { alert('clicked') }).html('<p>javascript</p>')
8.描述new一个对象的过程闭包
//建立一个对象 //this指向这个对象 //执行代码 即对this赋值 //返回this function Foo(name, age) { this.name = name this.age = age this.class = 'class-1' //return this 构造函数最好不要写return } var f = new Foo('zs', 20)
//执行上下文:当前被执行代码的环境/做用域 console.log(a) var a = 100 fn('zs') //函数声明 function fn(name) { console.log(this) console.log(arguments) age = 20 console.log(name, age) var age bar(100) function bar(num) { console.log(num) } } //函数表达式: var fn = function () {} //在全局代码执行前,会将变量定义和函数声明先提出来 //在函数代码执行前,会将变量定义,函数声明,this,arguments(全部参数的集合)先提出来
//this的值执行时才能肯定 var a = { name: 'A', fn: function () { console.log(this.name) //这个阶段的this没法肯定值 } } a.fn() //this === a a.fn.call({name: 'B'}) //this === {name: 'B'} var fn1 = a.fn fn1() //this === window //做为构造函数执行 function Foo(name) { // this = {} this.name = name // return this } var f = new Foo('zs') //做为对象属性执行 var obj = { name: 'A', printName: function () { console.log(this.name) //这里this就是obj } } obj.printName //做为普通函数执行 function fn() { console.log(this) //这里的this就是window } fn //call apply bind function fn1(name, age) { console.log(name) console.log(this) //这里的this是{x:100} } fn1.call({x:100}, 'zs', 20) var fn2h = function fn2(name, age) { console.log(name) console.log(this) //这里的this是{y:200} }.bind({y:200}) fn2('zs', 20)
//不断向父级做用域寻找变量的过程造成了做用域链 //没有块级做用域概念 if (true) { var name = 'zs' } console.log(name) //函数、全局做用域 var a = 10 function fn() { var a = 200 console.log('fn', a) } console.log('global', a) fn() var b = 100 function fn() { var c = 200 console.log(b) //当前做用域没有定义的变量叫作自由变量 console.log(c) } fn() var a = 100 function f1() { var b = 200 function f2() { var c = 300 console.log(a) console.log(b) console.log(c) } f2() } f1() //哪一个做用域定义了f1这个函数,f1的父级做用域就是谁
//闭包应用:1.函数做为返回值 function F1() { var a = 100 //返回一个函数 return function () { console.log(a) //100 } } //f1获得一个函数 var f1 = F1() var a = 200 f1() //2.函数做为参数传递 function F1() { var a = 100 return function() { console.log(a) //100 } } var f1 = F1() function F2(fn) { var a = 200 fn() } F2(f1)
9.说一下对变量提高的理解
变量定义、函数声明会提早。
10.说明this几种不一样的使用场景
做为构造函数、对象属性、普通函数执行,call apply bind
11.建立10个<a>
标签,点击时弹出对应序号app
var i for (i = 0; i < 10; i++) { (function (i) { var a = document.createElement('a') a.innerHTML = i + '<br>' a.addEventListener('click', function (e) { e.preventDefault() alert(i) }) document.body.appendChild(a) })(i) }
12.如何理解做用域
自由变量、做用域链,即自由变量的寻找、闭包的两个场景。
13.实际开发中闭包的应用
封装变量,收敛权限 案例:函数
function isFirstLoad() { var _list = [] return function (id) { if (_list.indexOf(id) >=0) { return false } else { _list.push(id) return true } } } var firstLoad = isFirstLoad() console.log(firstLoad(10)) console.log(firstLoad(10)) console.log(firstLoad(20)) console.log(firstLoad(20))