JS高级部分

Posted 大忽悠爱忽悠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS高级部分相关的知识,希望对你有一定的参考价值。

JS高级部分

判断

  • instanceof是用来区分对象的具体类型,因为所有对象都属于Object类型
  • typeof返回的是一个字符串
  • "== “会先把两端的变量试图转换成相同类型,然后再比较;”==="会直接去比较类型是否相同,如果类型相同则继续比较值是否相同。

对象引用类型


函数对象和数组对象都属于Object对象,Object对象是一个大的范围,而后两者是一个两种特别的对象


undefined与null的探究



区分变量类型和数据类型


数据,变量和内存



js的函数参数传递为值传递

当传入的是 基本类型的参数时:就是复制了份内容而已

当传入的是引用类型的参数时: 复制的是引用类型参数的地址


JS引擎如何管理内存


JS对象


什么时候需要使用[‘属性名’],什么时候需要使用.


JS函数对象

call和apply的区别

区别


回调函数


立即执行函数



JS函数中的this指向


JS分号问题




函数的原型对象





显示原型与隐式原型



原型链




原型链的属性问题


原型链是用来查找属性的,除非去给原型链添加属性,否则设置对象的属性值是,不会去管原型链的事情


instanceOf是如何判断的


总结

原型:

讲原型的时候,我们应该先要记住以下几个要点,这几个要点是理解原型的关键:

1、所有的引用类型(数组、函数、对象)可以自由扩展属性(除null以外)。

2、所有的引用类型都有一个’_ _ proto_ _'属性(也叫隐式原型,它是一个普通的对象)。

3、所有的函数都有一个’prototype’属性(这也叫显式原型,它也是一个普通的对象)。

4、所有引用类型,它的’_ _ proto_ _'属性指向它的构造函数的’prototype’属性。

5、当试图得到一个对象的属性时,如果这个对象本身不存在这个属性,
那么就会去它的’_ _ proto_ _'属性(也就是它的构造函数的’prototype’属性)中去寻找。

6.任何对象都有一个constructor属性,指向创建此对象的构造函数

7.原型对象中的constructor属性,也指向函数对象的构造函数

原型链:

当试图得到一个对象的属性时,如果这个对象本身不存在这个属性,
那么就会去它构造函数的’prototype’属性中去寻找。
那又因为’prototype’属性是一个对象,即原型对象,所以它也有一个’_ _ proto_ _'属性。

例如:

// 构造函数
		function Foo(name,age){
		 	this.name=name;
		 	this.age=age;
		}
		Object.prototype.toString=function(){
			//this是什么要看执行的时候谁调用了这个函数。
			console.log("I'm "+this.name+" And I'm "+this.age);
		}
		var fn=new Foo('小明',19);
		fn.toString(); //I'm 小明 And I'm 19
		console.log(fn.toString===Foo.prototype.__proto__.toString); //true
		
		console.log(fn.__proto__ ===Foo.prototype)//true
		console.log(Foo.prototype.__proto__===Object.prototype)//true
		console.log(Object.prototype.__proto__===null)//true

首先,fn的构造函数是Foo()。所以:
fn._ _ proto _ _=== Foo.prototype
又因为Foo.prototype是一个普通的对象,它的构造函数是Object,所以:
Foo.prototype._ _ proto _ _=== Object.prototype
通过上面的代码,我们知道这个toString()方法是在Object.prototype里面的,
当调用这个对象的本身并不存在的方法时,它会一层一层地往上去找,一直到null为止。


所以当fn调用toString()时,JS发现fn中没有这个方法,于是它就去Foo.prototype中去找,
发现还是没有这个方法,然后就去Object.prototype中去找,找到了,就调用Object.prototype中的toString()方法。


这就是原型链,fn能够调用Object.prototype中的方法正是因为存在原型链的机制。

另外,在使用原型的时候,一般推荐将需要扩展的方法写在构造函数的prototype属性中,避免写在_ _ proto _ _属性里面。


函数对象是Function的实例对象,同样也有隐式原型属性,但一般我们说的实例对象不包括函数对象

实例对象的隐式原型指向构造该实例对象的构造函数对象的显示原型

所有我们定义的函数,他们都是Object构造函数的实例,Object自己除外

Function构造函数用来构造Object构造函数对象,因此Object构造函数对象的隐式原型指向fucntion,它的显示原型不是function


测试题


解释:



一篇文章看懂_proto_和prototype的关系及区别


变量提升和函数提升



执行上下文


执行栈

javascript 执行在单线程上,所有的代码都是排队执行。

一开始浏览器执行全局的代码时,首先创建全局的执行上下文,压入执行栈的顶部。

每当进入一个函数的执行就会创建函数的执行上下文,
并且把它压入执行栈的顶部。当前函数执行完成后,当前函数的执行上下文出栈,并等待垃圾回收。

浏览器的 JS 执行引擎总是访问栈顶的执行上下文。


作用域


作用域链



闭包

闭包的定义


闭包的优点

1、让外部访问函数内部变量成为可能

2、局部变量会常驻在内存中

3、可以避免使用全局变量,防止全局变量污染

4、会造成内存泄漏(有一块内存空间被长期占用,而不被释放)


闭包的作用


变量f得到的是fn1返回的函数的地址值,fn3变量名被释放了,但是其所指向的地址又被f接收了,因此这块地址上的函数对象,没有成为垃圾对象被回收,还可以通过f进行调用


闭包的生命周期



闭包的应用—JS模块


JS模块定义方式一:

把上面这段代码写到一个js文件中,在html页面加载这个js文件的时候,js文件中的代码会执行,然后调用返回得到返回值执行即可

JS模块定义方式二:

这样js文件加载,我们通过myMoudle2.属性名()就可以直接调用函数


闭包的缺点



内存溢出与内存泄露


变量保存外部this



JS对象创建方式

方式一: Object构造函数模式


方式二: 对象字面量模式



方式三:工厂模式


方式四: 自定义构造函数模式



方式六: 构造函数+原型的组合模式



继承

原型链的继承

原型链的继承要点: 将对应的父类型的实例对象变为子类型的原型对象

当实现了原型链继承效果后,子类型原型的constructor指向的是刚才的添加进原型链的Supper,我们需要让子类型的原型的constructor指向子类型


借用构造函数实现伪继承



组合继承


这里用call得到属性,可以不通过原型对象去调用属性,而是可以直接通过.去调用属性


JS是单线程执行的

代码分类和JS代码执行的基本流程


事件循环模型


Web Worker实现多线程

Web Worker详解


总结





以上是关于JS高级部分的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript高级部分

XSS:如何从 C# 中的字符串中删除 JS 片段?

JS高级部分

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

Vue3官网-高级指南(十七)响应式计算`computed`和侦听`watchEffect`(onTrackonTriggeronInvalidate副作用的刷新时机`watch` pre)(代码片段

JS高级程序设计--笔记