知识点(二)
一、Js原型与原型链
如果试图引用对象(实例instance)的某个属性,会首先在对象内部寻找该属性,直至找不到,然后才在该对象的原型(instance.prototype)里去找这个属性.
__proto__ 属性是指定原型的关键
以上, 通过设置 __proto__ 属性继承了父类, 如果去掉new 操作, 直接参考如下写法
二、作用域与作用域链
js的作用域是靠函数来形成的,也就是说一个函数的变量在函数外不可以访问。
1、全局作用域
任何地方都能访问到的对象拥有全局作用域。
1.1函数外面定义的变量拥有全局作用域
1.2未定义直接赋值的变量自动声明为拥有全局作用域
1.3.window对象的属性拥有全局作用
2、局部作用域
局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部,所以在一些地方会把这种作用域成为函数作用域。
图一中,a是函数内部声明并赋值,拥有局部作用域,只能带函数fn内部使用,在fn外部使用就会报错,这就是局部作用域的特性,外部无法访问。
3、ES6的块级作用域
ES5只有全局作用域和函数作用域,没有块级作用域,
作用域链
通俗地讲,当声明一个函数时,局部作用域一级一级向上包起来,就是作用域链。
1.当执行函数时,总是先从函数内部找寻局部变量
2.如果内部找不到(函数的局部作用域没有),则会向创建函数的作用域(声明函数的作用域)寻找,依次向上
闭包
提到作用域就不得不提到闭包,简单来讲,闭包是指有权访问另一个函数作用域中的变量的函数
优点:闭包可以形成独立的空间,永久的保存局部变量。
缺点:保存中间值的状态缺点是容易造成内存泄漏,因为闭包中的局部变量永远不会被回收
三、vue渲染原理
在Vue1.0里面,模板实现跟Angular类似,如下图所示,把模板直接做成在浏览器里面parse成DOM树,然后去遍历这个树,提取其中的各种绑定。
在Vue2.0中,渲染层的实现做了根本性改动,那就是引入了虚拟DOM。
从架构来讲,Vue2.0 依然是写一样的模板,(Vue2.0于前段时间发布,具体报道:更轻更快的Vue.js 2.0)。在最左边,Vue2.0跟1.0的模板语法绝大部分是兼容的。Vue的编译器在编译模板之后,会把这些模板编译成一个渲染函数。而函数被调用的时候就会渲染并且返回一个虚拟DOM的树。这个树非常轻量,它的职责就是描述当前界面所应处的状态。当我们有了这个虚拟的树之后,再交给一个patch函数,负责把这些虚拟DOM真正施加到真实的DOM上。在这个过程中,Vue有自身的响应式系统来侦测在渲染过程中所依赖到的数据来源。在渲染过程中,侦测到的数据来源之后,之后就可以精确感知数据源的变动。到时候就可以根据需要重新进行渲染。当重新进行渲染之后,会生成一个新的树,将新树与旧树进行对比,就可以最终得出应施加到真实DOM上的改动。最后再通过patch函数施加改动。
这样做的主要原因是,在浏览器当中,JavaScript的运算在现代的引擎中非常快,但DOM本身是非常缓慢的东西。当你调用原生DOM API的时候,浏览器需要在JavaScript引擎的语境下去接触原生的DOM的实现,这个过程有相当的性能损耗。所以,本质的考量是,要把耗费时间的操作尽量放在纯粹的计算中去做,保证最后计算出来的需要实际接触真实DOM的操作是最少的。
四、webpack loader、合并项目
webpack
本身只能打包Javascript
文件,对于其他资源例如 css
,图片,或者其他的语法集比如jsx
,是没有办法加载的。 这就需要对应的loader
将资源转化,加载进来。
翻译过来:loader
就是一个export
出来的function
。
既然是 node module
,所以如果你自己要自定义一个loader
,完全可以这么写:
同时在 CommonComponents 目录下创建 index.js,其内容如下:
五、keep-live activity激活
是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。
需要在router
中设置router的元信息meta:
keep-alive生命周期钩子函数:activated、deactivated
使用<keep-alive>
会将数据保留在内存中,如果要在每次进入页面的时候获取最新的数据,需要在activated
阶段获取数据,承担原来created钩子中获取数据的任务。
六、promise
基本概念
Promise是一个构造函数,所以可以 new 出一个Promise的实例
在Promise上有两个函数 resolve(成功之后的回调函数)和 reject(失败后的回调函数)
在Promise构造函数的prototype属性上,有一个 .then() 方法。所以只要是Promise构造函数创建的实例,都可以访问到 .then()方法
Promise表示一个一步操作,每当我们new一个Promise的实例,这个实例就代表具体的异步操作。
Promise创建的实例,是一个异步操作,这个异步操作结果,只有两种结果
状态1:异步执行成功,需要在内部调用成功的回调函数resolve把结果返回给调用者
状态2:异步执行失败,需要在内部调用失败的回调函数reject把结果返回调用者
由于Promise的实例是一个异步操作,所以内部拿到操作结果后,无法使用return把操作结果返回给调用者,这个时候只能使用回调函数的形式,把成功或失败的结果,返回给调用者
我们可以在new出来的Promise实例上,调用 .then()方法,预先为这个Promise异步操作,指定成功(resolve)和失败(reject)回调函数
Promise中异常捕获两种方式的使用场景
需求 :前面的Promise执行失败,但是不要影响后续promise正常执行。
- 此时可以单独为每个promise通过.then()指定一下失败的回调
七、闭包
闭包就是指有权访问另一个函数作用域中的变量的函数。
创建闭包最常见方式,就是在一个函数内部创建另一个函数。
闭包只能取得包含函数中的任何变量的最后一个值
内存泄漏:闭包会引用包含函数的整个变量对象,如果闭包的作用域链中保存着一个HTML元素,那么就意味着该元素无法被销毁。所以我们有必要在对这个元素操作完之后主动销毁。
八、flex
display:flex;
flex-direction:row;
justify-content:space-between;
九、router
1、mode:history hash
2、this.$router.push({path: '/transport/dispatch', query: {paicheNo: obj.paicheNo})
this.$router.push({name: 'dispatch', params: {paicheNo: obj.paicheNo}})
十、父子组件通信
父组件向子组件传值
在Child.vue中创建props,用于接收父组件传递的值
子组件向父组件传值
在事件的函数中使用$emit来触发一个自定义事件,并传递一个参数,这个参数就是子组件要传递给父组件的值