Open moyahuang opened 4 years ago
javascript的逻辑运算符&&和||
//写出下面答案
var res={} || 'hello'
var res=null || undefined
var res={} && 'hello'
var res=null && undefined
答案:{} ; undefined; 'hello'; null 解释:a || b,若a为true返回a表达式,否则返回b表达式;a为false返回b表达式;&&与之相反。
js的内置对象Function, Object的原型对象的关系
Object.toString === Object.prototype.toString
答案:false 解释:因此Object.toString.call()和Object.prototype.toString.call()所接受的参数和结果都不同。 Object, Function虽然是内置对象,但更是构造函数。所有函数的原型对象 proto(已不推荐使用)都指向Function.prototype。特殊性原则:函数比对象特殊,因此Object 和Function的proto指向以函数的规则为准。(PS. 别忘了原型链的终点是Object.prototype哦)
什么叫plainObject? 我的理解是一般指由Object构造函数构造出来的对象就是plainObject。 所以window, document,new NonObjectConstructor,Object.create(null)等都不是plainObject。 注意:在jQuery3.0中认为Object.create({})创建的对象是plainObject。虽然和普通对象仍有区别,例 如Object.create({})的proto属性不指向Object.prototype,但是其构造函数属性值为Object。
var obj=Object.create({});
obj.__proto__===Object.prototype; //false
obj.constructor===Object; //true
防抖debounce 为什么防抖? 某些事件(例如keyup,keydown,mousemove,resize等)发生频率太快,而实际上用户往往不需要那么频繁的触发事件响应,从而影响用户体验。 算法思想:
function debounce(fn, wait, immediate){
var timer,result;
var debounced=function(){
var that=this;
var args=arguments;
clearTimeout(timer);
if(immediate){
timer=setTimeout(function(){
timer=null;
},wait);
if(!timer)result=fn.call(that,args);
}else{
timer=setTimeout(function(){
result=fn.call(that,args);
}, wait);
}
}
debounced.cancel=function(){
clearTimeout(timer);
timer=null;
}
return debounced;
}
节流throttle
//todo;
数组去重
类型判断(包括plainObject, 空对象,类数组对象,DOM元素等)
//核心是调用Object.prototype.toString
function type(args){
return Object.prototype.toString.call(args).split(" ")[1].slice(0,-1).toLowerCase();
}
//下面这种方法是经过我简化的,与原文不同,通过众多测试用例的判断暂时没出现问题
function isPlainObject(obj){
var proto;
if(type(obj)!=='object') return false;
proto=Object.getPrototypeOf(obj);
if(!proto) return false;
return proto.constructor === Object;
}
//对于什么叫类数组 可以自行根据场景定义 没有标准定义 jQuery中的实现条件就很宽松 略
function isEmptyObject(obj){
var item;
for(item in obj) return false;
return true
}
function isDOM(obj){
return !!(obj && obj.nodeType === 1);
}
深浅拷贝
求并/差/交集
模拟new的效果要注意:
function create(){
var obj=new Object();
var constructor=[].shift.call(arguments);//获取构造函数
obj.__proto__=constructor.prototype;
var res=constructor.**apply**(obj, arguments);//将构造函数的属性挂在obj上
return res instanceof Object?res:obj;
}
如何将arguments转换为数组 [].prototype.slice(arguments)
使用示例
var xhr=new XMLHttpRequest();
xhr.open("post","http://example.com/post", true);//false表示异步请求
xhr.onreadystatechange=function(){
if(xhr.readystate === 4){
if(xhr.status>=200 && xhr<300){
alert(xhr.responseText);
}
}
}
var data={ name:"moya", age:13};
//模拟POST表单提交
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(transform(data)));//参数不能为空
类型
值类型 vs. 引用类型
考点 1. 区别
2. 类型判断
3. 深浅拷贝 深浅拷贝的概念是相对于引用类型存在的。 数组的浅拷贝方法:
对象的浅拷贝方法
深拷贝方法: 深拷贝可能会碰到的坑
循环引用(环)
for(var key in obj){ if(obj.hasOwnProperty(key)){ newObj[key]=isObject(obj[key])?deepClone(obj[key]):obj[key]; } } return newObj; }
隐式类型转换
JS有6种值类型,
null
,undefined
,symbol
比较特殊,“正常”的也就3种number
,string
,boolean
,而类型转换的目标也就这三种类型。注意:
number
类型有1种特殊值NaN
隐式类型转换的3个场景分别对应3种转换目标
boolean
,number
,string
:if/!
等逻辑判断==
,算术以及关系运算)2种源类型:值类型和对象类型。
值类型的转换都有固定的规则,比较简单只列举特殊的几个:
转换为数字时:
对象类型的转换规则
所有的对象转换为布尔型都为
true
,所以需要讨论的情况是目标为number
以及string
。根据场景的不同,对象类型转换时所谓的
hint
也不同hint='string'
时,方法不存在或者返回值不为原始类型时,依次调用对象的以下方法:hint='number'和hint='default'
注:
+
,关系运算时,无法确定转换为string还是number时,规则和number一样,不需要特殊记忆特殊的数学运算:关系和+
关系运算可以通过以小(弱等)见大(若不等, >, <等)的方法推导
弱等(==)
string
或number
, 若运算数两者都有,则会将一方转换为数字类型+
+
会作为字符串拼接符原型和原型链
关于原型你需要知道的
__proto__
属性,属性值为一个普通对象,即其'原型'对象prototype
属性,属性值仍然是一个普通对象__proto__
指向对象Function.prototype
__proto__
对象指向其构造函数的prototype对象所谓原型链即访问某属性和方法时,从对象本身查找,如没找到则沿着
__proto__
逐层查找,直到找到终点Object.prototype(Object.prototype.proto=null)。继承
继承的核心就是将子类构造函数的原型对象设为父类的实例。
注意事项:
示例
测试用例
作用域和作用域链
概念:自由变量,闭包 考点
异步