复习汇总1

本文主要复习了JavaScript编程中的关键知识点,包括数据是函数的原因、this指向、面向对象编程与面向过程的区别、原型链、闭包、构造函数、回调函数、Promise、async/await的理解及其与Promise的区别、事件冒泡、Vuex的状态管理、组件通信方式、自定义指令和过滤器、路由守卫的执行流程、$route与$router的区别、Vue的hash模式和history模式、Vue的nextTick机制、<keep-alive>组件的作用、mixin混入及Proxy和Reflect对象的应用。内容涵盖了JavaScript的基础和高级特性,旨在巩固和深化对JavaScript编程的理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 1. 为什么data是函数?

因为是对象的话,多处引用,修改一个组件的值,其他组件的值也会发送改变,所有用返回对象的函数,每一次返回的都是object实例,因为存储地址不同,所以不会发送以上的问题

2. this指向?

普通函数中如果没有调用this, 那么他就指向window   在严格模式中就指向undefined

函数中有多个对象时即使这个函数是被最外层的对象调用那this也还是指向上一级对象

箭头函数中不绑定this所以它会捕获上下文的this值作为自己的值

1.在全局中this指向window

2.直接调用函数this指向window

3.事件处理函数中this指向绑定事件的元素

4.obj.fn(); fn函数中this指向obj

5.回调函数中this指向window

6.构造函数中this指向实例化对象

3. 面向对象编程与面向过程的区别: 

1)面向对象编程(面向对象特点: 封装 继承 多态 ):

1.面向对象编程是一个基于现实世界模型的一种编程方法

2.将属性抽象成一个对象,在这个对象上创建属性和方法

3.把函数封装变为对对象的封装

ps:创建对象的方法六种:

                1.直接给对象绑定属性和方法

                2.通过字面量方式创建

                3.工厂函数   4.构造函数模式    5.原型模式     6.混合模式

2)面向过程编程:

分析实现效果的步骤,然后按照步骤用函数一步一步实现

ps:构造函数模式与工厂函数的区别:

                工厂函数return返回 方法不一样

 4. proto与prototype的关系/区别:

 __proto__是隐式原型

prototype是显示原型:用来实现基于原型的继承与属性的共享

可通过Object.getPrototypeOf()标准方法访问该属性),指向构造函数的原型对象。

5. 原型链:

每一个对象都要自己的原型_proto_ , 这个原型也有他自身的原型对象prototype ,以此类推, 上升到了object.prototype, 而object.prototype的_proto_是null , null没有属性和方法, 原型链尽头是null. 

 5.面向对象的继承

原型继承    构造函数继承    实例继承     组合继承    寄生组合继承    class类继承 

6.闭包原理:

函数中的函数读取函数内部的变量

优点:   1.能够读取函数内部的变量. 2.让这些变量一直存在于内存中,不会在调用结束后,被垃圾回收机制回收

缺点: 因为闭包会使函数中的变量保存在内存中,内存消耗大,所以不能滥用闭包

解决办法: 退出函数前,将不使用的局部变量删除 

 7. 构造函数原理

构造函数是一种特殊方法,用于初始化对象.在类的对象创建时,构造函数将被调用

优点: 能够通过instanceof识别对象

缺点: 每次实例化一个对象,都会把属性和方法复制一遍

解决办法: 把对象的方法指向同一个全局函数 通过原型对象(prototype),把方法写在构造函数的原型上

8. 回调函数

回调函数是一段可执行的代码段它作为一个参数传递给其他的代码

其作用是在需要的时候方便调用这段(回调函数)代码

优点: 简单,容易理解和实现

缺点: 不利于代码的阅读和维护,各个部分之间高度耦合(coupling)使得程序结构混乱,流程难以追踪,每个任务只能指定一个回调函数 

9.说一说你对promise的理解。

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。

Promise有哪些状态。 答:有三个状态:pending : 等待 fullfilled(resolved) :成功 rejected: 失败 

所谓promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。

Promise.all(),一个失败后,其他的还返回吗? 答:不会返回,promise.all()失败的时候只返回最先被reject失败状态的那个实例对象的值

Promise.all()、Promise.race()区别? 答:两者都是可以同时调用多个promise实现,Promise.all可以将多个实例组装成一个新的实例,成功的时候返回一个成功数组,失败的时候则返回最先被reject失败状态的值;其中有一个实例不成功则返回reject; race()是赛跑的意思,也就是说Promise.race([p1, p2, p3])里面的结果哪个获取的快,就返回哪个结果,不管结果本身是成功还是失败

10.简单说一下async/await的了解?(****)(请参考https://www.jianshu.com/p/fd6933ff6b81)  

答:async/await是写异步代码的新方式,它是generator的语法糖,以前的方法有回调函数和 Promise。async/await是基于Promise实现的,它不能用于普通的回调函数。 async/await与Promise一样,是非阻塞的。async/await使得异步代码看起来像同步代码,这正是它的魔力所在。单一的 Promise 链并不能发现 async/await 的优势, 但是,如果需要处理由多个 Promise 组成的 then 链的时候,优势就能体现出来了

11.Async&await和promise有什么区别?(参考https://www.jianshu.com/p/51f5fd21588e)

答: (1)函数前面多了一个async关键字。await关键字只能用在async定义的函数内。async函数会引式返回一个promise

(2)简洁:使用async和await明显节约了不少代码,不需要.then,不需要写匿名函数处理promise的resolve的值,不需要定义多余的data变量,还避免了嵌套代码。

(3)async/await让try/catch 可以同时处理同步和异步错误。try/catch不能处理JSON.parse的错误,因为他在promise中。此时需要.catch,这样的错误处理代码非常冗余。并且,在我们的实际生产代码会更加复杂

(4)async/await能够使得代码调试更简单 

12、写出本地存储和cookie的区别

本地存储:   可以设置有效期限 存储空间只有4KB左右

cookie优缺点

        cookie机制将信息存储于浏览器,因此可以作为跨页面全局变量,这是它最大的一个优点

常用场合:(1)保存用户登录状态;(2)跟踪用户行为.等等

cookie的缺点

(1)cookie可能被禁用; (2)cookie与浏览器相关,不能互相访问; (3)cookie可能被用户删除; (4)cookie安全性不够高; (5)cookie存储空间很小(只有4KB左右)

用escape( )函数进行编码 unescape( )进行解码才能

expires=data  设置有效期

localStorage 

HTML5 本地存储:

大小最小5MB,可以申请更大的空间

 不会随HTTP请求发送给服务器

 非常容易操作   移动端普及高 

localStorage与sessionStorage两种: 

                localStorage l localStorage为永久性保存数据,不会随着浏览器的关闭而消失,可以在同域名跨页访问。 l 按域名进行存储,不会和其他域名冲突 l 键值对存储:key/value 

13. localStorage和sessionStorage是Web提供的两种本地存储方式。

相比较cookie而言,localStorage和sessionStorage的存储大小很大,localStorage能够长期保存,sessionStorage在会话期间保存。

localStorage和sessionStorage都是window对象提供的全局属性,用途都是在浏览器中存储key/value对的数据。

从使用的角度来看,两者的唯一区别在于时效性。

sessionStorage在关闭窗口或标签页之后将会删除这些数据。

而localStorage则没有这样的特性,它的数据一直都在,除非你手动去删除。

如果你想在浏览器窗口关闭后还保留数据,请使用localStorage。

如果你是想用于临时保存同一窗口(或标签页)的数据,请使用sessionStorage。

 14.Vue2和vue3的响应式原理分别是什么,以及vue3为什么要更改实现响应式原理的方式

vue2.x用的核心函数是Object.defineProperty,defineProperty核心并不是为对象做数据绑定的,而是给对象的属性做一些配置, 只不过里面的set和get实现了。

响应式defineProperty的缺陷是只能监听一个属性,所以要想监听一个对象,

vue2的内部做了一个 for in 处理

而vue3用proxy写,proxy可以监听整个对象。省去for in提升效率,并且可以监听数组,不用再去单独的对数组做特异性操作

 15.proxy和defineProperty的区别

Object.defineProperty 无法监控到数组下标的变化,导致通过数组下标添加元素,不能实时响应;

Object.defineProperty只能劫持对象的属性,从而需要对每个对象,每个属性进行遍历,如果,属性值是对象,还需要深度遍历。

Proxy 可以劫持整个对象,并返回一个新的对象

Proxy 不仅可以代理对象,还可以代理数组。还可以代理动态增加的属性

Proxy 相比于 defineProperty 的优势 ?

数组变化也能监听到      不需要深度遍历监听

16.Async函数用法和promise区别

答:简单的说async函数就相当于自执行的Generator函数,相当于自带一个状态机, 在await的部分等待返回, 返回后自动执行下一步。

而且相较于Promise,async的 优越性就是把每次异步返回的结果从then中拿到最外层的方法中,不需要链式调用, 只要用同步的写法就可以了。更加直观而且,更适合处理并发调用的问题。

但是async 必须以一个Promise对象开始 ,所以async通常是和Promise结合使用的。

总的来说, async函数主要就是为了解决异步的并发调用使用的 ,直接将参数从then里取出来, 相比promise的链式调用,传参更加方便,异步顺序更加清晰。 

17.简单说一下事件冒泡

答:IE 的事件流叫做事件冒泡(event bubbling),即事件开始时由最具体的元素(文档中嵌套层次最深 的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)。

事件沿 DOM 树向上传播,在每一级节点上都会发生,直至传播到 document 对象。

所有现代浏览器都支持事件冒泡,但在具体实现上还是有一些差别。

IE5.5 及更早版本中的事件冒泡会跳过<html>元素(从<body>直接跳到 document)。

IE9、Firefox、Chrome 和 Safari 则将事件一直冒泡到 window 对象。 

18.为什么Vuex中的state数据不放到data里面而放在computed里面

data只会在进入页面的时候初始化一次,计算属性会实时更新 

19.声明式与编程式

声明式导航是写在template标签里,通过<router-link to=''></router-link>标签来触发

编程式导航写在js里,通过this.$router.push(xxx)来触发路径 

ps:  .split('').reverse().join('');拆分 倒序 重组  

20.编程式中push有浏览记录 replace不会有浏览记录 

注意:在 Vue 实例内部,你可以通过 $router 访问路由实例。

因此你可以调用 this.$router.push。

想要导航到不同的 URL,则使用 router.push 方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。

当你点击 <router-link> 时,这个方法会在内部调用,所以说,点击 <router-link :to="..."> 等同于调用 router.push(...)。

该方法的参数可以是一个字符串路径,或者一个描述地址的对象。

例如: // 字符串 router.push('home')     // 对象 router.push({ path: 'home' })      // 命名的路由 router.push({ name: 'user', params: { userId: '123' }})        // 带查询参数,变成 /register?plan=private router.push({ path: 'register', query: { plan: 'private' }})

注意:如果提供了 path,params 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name 或手写完整的带有参数的 path

const userId = '123'

router.push({ name: 'user', params: { userId }}) // -> /user/123

router.push({ path: `/user/${userId}` }) // -> /user/123

// 这里的 params 不生效

router.push({ path: '/user', params: { userId }}) // -> /user

ps:同样的规则也适用于 router-link 组件的 to 属性。

 21.route懒加载动态导入

当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块, 然后当路由被访问的时候才加载对应组件,这样就会更加高效。

Vue Router 支持开箱即用的动态导入,这意味着你可以用动态导入代替静态导入:

// 将  import UserDetails from './views/UserDetails' 静态导入

 替换成 

const UserDetails = () => import('./views/UserDetails') 动态导入

有时候我们想把某个路由下的所有组件都打包在同个异步块 (chunk) 中

只需要使用命名 chunk,一个特殊的注释语法来提供 chunk name const UserDetails = () => import(/* webpackChunkName: "group-user" */ './UserDetails.vue') const UserDashboard = () => import(/* webpackChunkName: "group-user" */ './UserDashboard.vue') const UserProfileEdit = () => import(/* webpackChunkName: "group-user" */ './UserProfileEdit.vue') webpack 会将任何一个异步模块与相同的块名称组合到相同的异步块中。

 23.组件通信: 

vuex(三种):

父传子(props):在父组件自定义属性名传递数据,在父组件在引入和挂载子组件,在父组件使用它,
在标签上绑定你想传入的数据,在子组件上用props接受数据,并且使用它

子传父($emit): 父组件向子组件传递事件方法,子组件通过$emit触发事件,回调给父组件

兄弟通信bus(需要有共同的父组件)
            设定事件中心vue实例    中央通信    let bus = new vue()
            A:methods:{函数{bus.$emit("自定义事件名",数据)}}  发送
            B:created(){bus.$on("A发送过来的自定义事件名",函数)}  进行数据接受

provide&inject:

组件跟后代的通信方法是不可响应的 provide传入 inject注入 父组件以provide将自己的数据以对象方式传出去

$parent&$children:

$parent获取所有父组件 $children获取所有子组件 获取不到的原因是因为created创建后DOM还没有出来所以用mounted

$listeners&$attrs:

跨组件传值  $attrs获取所有父组件里面的属性不包含props传过的

                    $listeners自定义的事件传入方法 

$parent与$attrs有什么区别?

$parent获取所有父组件 $attrs也是获取所有父组件但是不包含props传过的 不自定义属性也是获取不到

 24.自定义指令

默认内置指令与自定义指令

自定义指令有 全局 跟 局部

Vue.directive('style', {

        // 当被绑定的元素插入到 DOM 中时……

        bind: function (el) {

        // 聚焦元素 el.style.backgroundColor='res'

        }

})

bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。 一般用于属性

inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。 一般用于DOM

update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。 我们会在稍后讨论渲染函数时介绍更多 VNodes 的细节。

componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。

unbind:只调用一次,指令与元素解绑时调用。

指令钩子函数会被传入以下参数:

        el:指令所绑定的元素,可以用来直接操作 DOM。

        binding:一个对象,包含以下 property:

        name:指令名,不包括 v- 前缀。

        value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。

        oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。

        expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"。

        arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"。

        modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。

        vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。

        oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

inserted:function(el,binding){

        for(var emo in binding.value){

                el.style[emo]=binding.value[emo]

        }

}

 25.vue-过滤器:

1、vue过滤器简介 vue过滤器就是用来过滤模型数据,在显示之前进行数据处理和筛选。

2、vue过滤器使用语法 语法:{{ data | filter1(参数) | filter2(参数) }}

3、vue内置过滤器 使用自定义过滤器

4、自定义过滤器 分类:全局过滤器,局部过滤器

1 自定义全局过滤器 语法:使用全局方法Vue.filter(过滤器ID,过滤器函数),过滤器写在window.οnlοad=function(){ new Vue...} /export default  的外面。

2 自定义局部过滤器 语法:使用局部方法filters:{过滤器ID:(过滤器参数1,过滤器参数2...)=>{函数回调}},过滤器写在new Vue里面。

 forEach用于数组遍历 for in 用于对象遍历

 Object.keys(obj)参数:要返回其枚举自身属性的对象返回值:一个表示给定对象的所有可枚举属性的字符串数组

Object.values()返回一个数组,成员是参数的对象自身的(不含继承)所有可遍历属性的键值

26.路由守卫的执行过程:

全局前置守卫beforeEach---->路由独享守卫beforeEnter---->组件内的守卫beforeRouteEnter/beforeRouteUpdate/beforeRouteLeave---->全局解析守卫beforeResolve---->全局后置钩子afterEach 组件内守卫--进入 组件内守卫--切换 组件内守卫--离开 全局后置钩子afterEach

ps:    afterEach没有next()钩子 

        beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。 

27.$route和$router的区别

$route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数。

而$router是“路由实例”对象包括了路由的跳转方法,钩子函数等 

28.Vue中hash模式和history模式的区别

在最明显的显示上:

hash模式的URL中会夹杂着#号,而history没有。

Vue底层对它们的实现方式不同:

        hash模式是依靠onhashchange事件(监听location.hash的改变)

        history模式是主要是依靠的HTML5 history中新增的两个方法,

                pushState()可以改变url地址且不会发送请求,

                replaceState()可以读取历史记录栈,还可以对浏览器记录进行修改。window.onhashchange = function(event){

        // location.hash获取到的是包括#号的,如"#heading-3"

        // 所以可以截取一下 let hash = location.hash.slice(1);

}

ps: 当真正需要通过URL向后端发送HTTP请求的时候,比如常见的用户手动输入URL后回车,或者是刷新(重启)浏览器,这时候history模式需要后端的支持。因为history模式下,前端的URL 必须和实际向后端发送请求的URL一致,例如有一个URL是带有路径path的(例如www.libai.wang/blogs/id),如果后端没有对这个路径做处理的话,就会返回404错误。所以需要后端增 加一个覆盖所有情况的候选资源,一般会配合前端给出的一个404页面。 

当活动历史记录条目更改时,将触发popstate事件。

如果被激活的历史记录条目是通过对history.pushState()的调用创建的,或者受到对 history.replaceState()的调用的影响,popstate事件的state属性包含历史条目的状态对象的副本。

需要注意的是调用history.pushState()或history.replaceState()不会触发popstate事件。

只有在做出浏览器动作时,才会触 发该事件,如用户点击浏览器的回退按钮(或者在Javascript代码中调用history.back()或者history.forward()方法) 

29.nextTick

nextTick可以让我们在下次 DOM 更新循环结束之后执行延迟回调,用于获得更新后的 DOM nextTick主要使用了宏任务和微任务。

根据执行环境分别尝试采用 Promise  Mutation  Observer  setImmediate 

如果以上都不行则采用setTimeout 定义了一个异步方法,多次调用nextTick会将方法存入队列中,通过这个异步方法清空当前队列

30. <keep-alive></keep-alive>的作用是什么?

keep-alive可以实现组件缓存,当组件切换时,主要用于保留组件状态或避免重新渲染

使用场景:比如有一个列表和一个详情,那么用户就会经常执行打开详情=>返回列表=>打开详情…这样的话列表和详情都是 一个频率很高的页面,那么就可以对列表组件使用<keep-alive></keep-alive>进行缓存,这样用户每次返回列表的时候, 都能从缓存中快速渲染,而不是重新渲染

常用的两个属性include/exclude,允许组件有条件的进行缓存

两个生命周期activated/deactivated,用来得知当前组件是否处于活跃状态 

31.mixins: 

mixins 选项接收一个混入对象的数组。

这些混入对象可以像正常的实例对象一样包含实例选项,这些选项将会被 合并到最终的选项中,使用的是和 Vue.extend() 一样的选项合并逻辑。

也就是说,如果你的混入包含一个 created 钩子,而创建组件本身也有一个,那么两个函数都会被调用。

Mixin钩子按照传入顺序依次调用,并在调用组件自身的钩子之前被调用。 

 32.Proxy 

Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。

Object.defineProperty的作用----> 用来给对象新增属性,和修改对象中的属性。 

writable、enumerable、configurable为false的情况        

wirtable:变量不可再被重新赋值

enumerable: 变量不能在遍历器例如for...in和Object.keys()中被读取出来,不可被遍历

configurable:变量不可配置,定义为false之后,不能再为该变量定义配置否则报错。变量被删除(delete)、修改都会无效。

如果对象的属性是存取描述符,只会调用定义了的set和get(configurable、enumrable)

在给一个对象属性做赋值操作,在读取属性值时,这个赋值操作赋值的值会被忽略,会去调用定义的get方法的值

Proxy 相比于 defineProperty 的优势

Object.defineProperty() 的问题主要有三个:

不能监听数组的变化      必须遍历对象的每个属性     必须深层遍历嵌套的对象

Proxy 在 ES2015 规范中被正式加入,它有以下几个特点

针对对象:针对整个对象,而不是对象的某个属性,所以也就不需要对 keys 进行遍历。这解决了上述 Object.defineProperty()

支持数组:Proxy 不需要对数组的方法进行重载,省去了众多 hack,减少代码量等于减少了维护成本,而且标准的就是最好的。

除了上述两点之外,Proxy 还拥有以下优势:

Proxy 的第二个参数可以有 13 种拦截方法,这比起 Object.defineProperty() 要更加丰富 Proxy 作为新标准受到浏览器厂商的重点关注和性能优化,相比之下 Object.defineProperty() 是一个已有的老方法。

get(target, propKey, receiver):拦截对象属性的读取,比如proxy.foo和proxy['foo']。 set(target, propKey, value, receiver):拦截对象属性的设置,比如proxy.foo = v或proxy['foo'] = v,返回一个布尔值。

getPrototypeOf(target):拦截Object.getPrototypeOf(proxy),返回一个对象。 setPrototypeOf(target, proto):拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值

Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程。

Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问 进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。

Proxy 支持的拦截操作一览,一共 13 种。

        get(target, propKey, receiver):拦截对象属性的读取,比如proxy.foo和proxy['foo']。

        set(target, propKey, value, receiver):拦截对象属性的设置,比如proxy.foo = v或

proxy['foo'] = v,返回一个布尔值。

        has(target, propKey):拦截propKey in proxy的操作,返回一个布尔值。

        deleteProperty(target, propKey):拦截delete proxy[propKey]的操作,返回一个布尔值。

        ownKeys(target):拦截    

        Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy)、for...in循环,

返回一个数组。该方法返回目标对象所有自身的属性的属性名,而Object.keys()的返回结果仅包括目标对象自身的可遍历属性。

        getOwnPropertyDescriptor(target, propKey):拦截Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象

        defineProperty(target, propKey, propDesc):拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs), 返回一个布尔值。

        preventExtensions(target):拦截Object.preventExtensions(proxy),返回一个布尔值。         getPrototypeOf(target):拦截Object.getPrototypeOf(proxy),返回一个对象。         isExtensible(target):拦截Object.isExtensible(proxy),返回一个布尔值。

        setPrototypeOf(target, proto):拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。

         apply(target, object, args):拦截 Proxy 实例作为函数调用的操作,比如proxy(...args)、proxy.call(object, ...args)、proxy.apply(...)。

         construct(target, args):拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(...args)。

Proxy 实例的方法

get() -------get方法用于拦截某个属性的读取操作,可以接受三个参数,依次为目标对象、属性名和 proxy 实例本身(严格地说,是操作行为所针对的对象),其中最后一个参数可选。 get方法可以继承。

set() -------set方法用来拦截某个属性的赋值操作,可以接受四个参数,依次为目标对象、属性名、属性值和 Proxy 实例本身,其中最后一个参数可选。 假定Person对象有一个age属性,该属性应该是一个不大于 200 的整数,那么可以使用Proxy保证age的属性值符合要求。

has()-------has()方法用来拦截HasProperty操作,即判断对象是否具有某个属性时,这个方法会生效。典型的操作就是in运算符。 has()方法可以接受两个参数,分别是目标对象、需查询的属性名。、

construct()------construct()方法用于拦截new命令 construct()方法可以接受三个参数。 target:目标对象。 args:构造函数的参数数组。 newTarget:创造实例对象时,new命令作用的构造函数 deleteProperty() deleteProperty方法用于拦截delete操作,如果这个方法抛出错误或者返回false,当前属性就无法被delete命令删除。 deleteProperty方法拦截了delete操作符,删除第一个字符为下划线的属性会报错。 目标对象自身的不可配置(configurable)的属性,不能被deleteProperty方法删除,否则报错。

defineProperty()---------defineProperty()方法拦截了Object.defineProperty()操作。 如果目标对象不可扩展(non-extensible),则defineProperty()不能增加目标对象上不存在的属性,否则会报错。另外,如果目标对 象的某个属性不可写(writable)或不可配(configurable),则defineProperty()方法不得改变这两个设置。

getOwnPropertyDescriptor()--------getOwnPropertyDescriptor()方法拦截Object.getOwnPropertyDescriptor(),返回一个属性描述对象或者undefined。 handler.getOwnPropertyDescriptor()方法对于第一个字符为下划线的属性名会返回undefined。

getPrototypeOf()---------getPrototypeOf()方法主要用来拦截获取对象原型。具体来说,拦截下面这些操作。

        Object.prototype.__proto__

        Object.prototype.isPrototypeOf()

        Object.getPrototypeOf()

        Reflect.getPrototypeOf()

        instanceof

        getPrototypeOf()方法的返回值必须是对象或者null,否则报错。另外,如果目标对象不可扩展(non-extensible), getPrototypeOf()方法必须返回目标对象的原型对象。

        

33.文件信息

├── build --------------------------------- webpack相关配置文件
│ ├── build.js --------------------------webpack打包配置文件
│ ├── check-versions.js ------------------------------ 检查npm,nodejs版本
│ ├── dev-client.js ---------------------------------- 设置环境
│ ├── dev-server.js ---------------------------------- 创建express服务器,配置中间件,启动可热重载的服务器,用于开发项目
│ ├── utils.js --------------------------------------- 配置资源路径,配置css加载器
│ ├── vue-loader.conf.js ----------------------------- 配置css加载器等
│ ├── webpack.base.conf.js --------------------------- webpack基本配置
│ ├── webpack.dev.conf.js ---------------------------- 用于开发的webpack设置
│ ├── webpack.prod.conf.js --------------------------- 用于打包的webpack设置
├── config ---------------------------------- 配置文件
├── node_modules ---------------------------- 存放依赖的目录
├── src ------------------------------------- 源码
│ ├── assets ------------------------------ 静态文件
│ ├── components -------------------------- 组件
│ ├── main.js ----------------------------- 主js
│ ├── App.vue ----------------------------- 项目入口组件
│ ├── router ------------------------------ 路由
├── package.json ---------------------------- node配置文件
├── .babelrc--------------------------------- babel配置文件
├── .editorconfig---------------------------- 编辑器配置
├── .gitignore------------------------------- 配置git可忽略的文件

34.Reflect对象 :

 Reflect对象与Proxy对象一样,也是 ES6 为了操作对象而提供的新 API。

Reflect对象的设计目的有这样几个。

        (1) 将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上。现阶段,某些方法同时在Object和Reflect对象上部署,未来的新方法将只部署在Reflect对象上。也就是说,从Reflect对象上可以拿到语言内部的方法。 

        (2) 修改某些Object方法的返回结果,让其变得更合理。比如,Object.defineProperty(obj, name, desc)在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)则会返回false。

        (3) 让Object操作都变成函数行为。某些Object操作是命令式,比如name in obj和delete obj[name],而Reflect.has(obj, name)和Reflect.deleteProperty(obj, name)让它们变成了函数行为。

        (4)Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。

也就是说,不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为。

Reflect对象一共有 13 个静态方法。

         Reflect.apply(target, thisArg, args)

        Reflect.construct(target, args)

        Reflect.get(target, name, receiver)

        Reflect.set(target, name, value, receiver)

         Reflect.defineProperty(target, name, desc)

        Reflect.deleteProperty(target, name)

         Reflect.has(target, name)

        Reflect.ownKeys(target)

        Reflect.isExtensible(target)

         Reflect.preventExtensions(target)

        Reflect.getOwnPropertyDescriptor(target, name)

         Reflect.getPrototypeOf(target)

        Reflect.setPrototypeOf(target, prototype)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

甜宝小妮儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值