new
- 创建一个空对象,并且this变量引用该对象,同时还继承了该函数的原型;
- 属性和方法被加入到this引用的对象中;
- 新创建的对象由this所引用,并且最后隐式的返回this
var obj = {}
obj._proto__ = Base.prototype;
Base.call(obj)
JSON
JSON是一种轻量级的数据交换格式,它是基于JS的一个子集;
数据格式简单,易于读写,传输占用带宽小.
{
"age":"12",
"name":"Jack"
}
JSON 对象包含两个方法:
- 用于解析JSON的**parse()**方法
- 将对象/值转换为JSON字符串的**stringify()**方法
除了这两个方法,JSON这个对象本身并没有其他作用,也不能被调用或者作为构造函数调用.
document.write innerHTML
- document.write只能重绘整个页面;
- innerHTML可以重绘页面的一部分.
call和apply
核心
动态改变某个类的某个方法的运行环境,就是改变this关键字
- call是参数一个一个的传
- apply是把参数当作一个数组传进去,类似arguments
区别
- Function.prototype.call 和Function.prototype.apply 她们的作用一样,区别仅在于传入的参数的形式不同;
- 当使用call或者apply的时候,如果我们传入的第一个参数是null,函数体内的this会指向默认的宿主对象,在浏览器中则是window
- 由时候我们使用call或者apply的目的不在于指定this的指向,而是另有用途.例如:借用其他对象的方法.那么我们可以传入null来代替某个具体发对象.
call和apply的用途
- 改变this的指向
- Function.prototype.bind
- 借用其他对象的方法
function add(a,b){
console.log(a+b);
}
function sub(a,b){
console.log(a-b)
}
add.call(sub,3,1)
用add来替换sub,add.call(sub,3,1) == add(3,1) //4
js 中的函数其实是对象,函数名是对FUnction对象的引用
哪些操作会造成内存泄漏
内存泄漏是指任何对象在不再拥有或者需要它之后仍然存在.
还有一种说法:内存泄漏指分配给应用的内存不能被重新分配,即使在内存已经不被使用的时候.
垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量.如果一个对象的引用数量为0(没有其他对象引用过该对象),或对该对象的唯一引用是循环的,那么该对象的内存即可回收.
- setTimeout的第一个参数使用字符串而非函数的话,会引发内存泄漏.
- 闭包.因为JS范围的限制,许多实现依赖JS闭包.闭包可以导致内存泄漏是因为内部方法保持一个对外部变量的引用,所以尽管方法返回了内部方法还可以继续访问在外部方法中定义的私有变量.对JS程序员来说最好的做法是在页面重载前断开所有事件处理器.
- 控制台日志
- 循环引用:在两个对象彼此引用且保留彼此时,就会产生一个循环.
- DOm插入顺序.当两个不同范围的DOM对象添加到一起时,一个临时的对象被创建.这个DOM对象改变范围到document时,那个临时对象就没有用了.也就是说,DOM对象应该按照从当前页面存在的最上面的DOM元素开始向下直到剩下的DOM元素的顺序添加.这样她们就总有相同的范围,不会产生临时对象.
eval()
**eval()**函数,这个函数可以把一个字符串当作一个JS表达式一样去执行它.它的功能是把对应的字符串解析为JS代码并运行.
应该避免使用eval(),不安全,耗性能.需要执行两次:一次解析为JS代码,一次执行.
JS对象的深度拷贝
function clone(obj){
if(typeof(obj) != 'object')
return obj;
var r = Array.prototype.splice === obj.splice?[]:{};
for(var i in obj){
if(obj.hasOwnProperty(i)){
r[i] = clone(obj[i])
}
}
return r;
}
数组对象都可以用for in,同时针对对象必须要判断hasOwnProperty属性,以防止克隆原型链上的属性.
浅拷贝
Object.assign()
浏览器的严格模式\混杂模式
严格模式
又称标准模式,是指浏览器按照W3C标准解析代码
混杂模式
又称怪异模式或者兼容模式,是指浏览器用自己的方式解析代码
区分
浏览器使用严格模式韩式混杂模式,与网页中的DTD(Document Type Definition)直接相关.
this对象
- this指的是调用函数的那个对象
- this在没有运行之前不能知道代表谁,js的this指向是不确定的,和定义没有关系,和执行有关
- 执行的时候,点前面是谁,this就是谁;自执行函数里面的this代表的是window
- 定时器书写的时候,window可以省略;定时器执行的时候,里面的this代表的也是window
- thiis是一个关键字,随着函数使用场合的不同,this的值会发生变化
原则 - this指的是调用函数的那个对象,如果没有被调用,则未知
- this一般情况下:是全局对象Global.作为方法的调用,this指这个对象
window对象 Document对象
- documen是window的一个对象属性
- window对象表示浏览器中打开的窗口
- 如果文档包含框架(frame/iframe),浏览器会为HTML创建一个window对象,并为每个框架创建一个额外的window对象
- 所有的全局对象和对象都属于window对象的属性和方法
- document对DOcument对象的只读引用
typeof(null)
返回object
原因:null本身属于Object;万物皆对象;
但typeof返回的不准确
如何精确判断null类型
Object.prototype.toString.call(data)
封装如下:
let _typeof = function(data){
let value = /\[object(\w+)\]/.exec(
Object.prototype.toString.call(data)
);
return value?value[1].toLowerCase():''
}
此时typeof(null)返回’null’
[“1”,“2”,“3”].map(parseInt)
[1,NaN,NaN]
原因:
map()方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果.
[1,NaN,NaN]因为parseInt需要两个参数(val,index)但是map传了3个(element,index,array)
而parseInt需要两个参数中的index表示解析时用的基数
map传的(element,index,array),对应的index不合法导致失败.
作用链域
- 子域访问父域,函数可以限定变量的作用域,那么在函数中的函数就成为该作用域的子域
- 在子域中的代码可以访问到父域中的变量,由了JS作用域的划分,可以将JS的访问作用域连成一个链式树状结构
- 由了JS作用域的划分,可以将JS的访问作用域连成一个链式树状结构
1)作用域链就是对象的数组
2)全部script时0级链,每个对象占一个位置
3)凡是看到函数延伸出一个链出来,一级级展开
4)访问首先看当前函数,如果没有定义往上一级链检查
5)如此往复,直到0级链