当前位置: 首页 > news >正文

前端优化网站官方网站开发制作公司

前端优化网站,官方网站开发制作公司,pc端网站怎么做自适应手机端,厦门营销网站建设写于 2017年08月20日#xff0c;虽然是2017年写的文章#xff0c;但现在即将2020年依旧不过时#xff0c;现在补充了2019年新增的ES10 Object.fromEntries()。发到公众号申明原创。若川顺便在此提前祝大家#xff1a;2020年更上一层楼。近日发现有挺多人对对象基础API不熟悉… 写于 2017年08月20日虽然是2017年写的文章但现在即将2020年依旧不过时现在补充了2019年新增的ES10 Object.fromEntries()。发到公众号申明原创。若川顺便在此提前祝大家2020年更上一层楼。近日发现有挺多人对对象基础API不熟悉举个开发中常见的需求经常会有类似的封装http到原型Vue.prototype一般人是这样封装的但容易被篡改。function Vue(){console.log(test vue); } function http(){console.log(我是调用接口的http); } Vue.prototype.$http http; var vm new Vue(); vm.$http() vm.$http 1; // 一旦被修改虽然一般正常情况下不会被修改 vm.$http(); // 再次调用报错 熟悉Object.defineProperty或者说熟悉对象API的人一般是如下代码写的则不会出现被修改的问题。function Vue(){console.log(test vue); }; function http(){console.log(我是调用接口的http); }; Object.defineProperty(Vue.prototype, $http, {get(){return http;} }); var vm new Vue(); vm.$http(); vm.$http 1; // 这里无法修改 vm.$http(); // 调用正常 vue-router 源码里就是类似这样写的[1]this.$routerthis.$route无法修改。// vue-router 源码 Object.defineProperty(Vue.prototype, $router, {get () { return this._routerRoot._router } }) Object.defineProperty(Vue.prototype, $route, {get () { return this._routerRoot._route } }) 以下是正文祝阅读愉快~之前看到【深度长文】JavaScript 数组所有 API 全解密[2]和JavaScript 字符串所有 API 全解密[3]这两篇高质量的文章。发现没写对象 API 解析估计是博主觉得简单就没写。刚好我看到《JavaScript 面向对象编程指南第 2 版》觉得有必要写或者说 chao一下也好熟悉下对象的所有 API 用法。创建对象的两种方式var o new Object(); var o {}; // 推荐 该构造器可以接受任何类型的参数并且会自动识别参数的类型并选择更合适的构造器来完成相关操作。比如var o new Object(something); o.constructor; // ƒ String() { [native code] } var n new Object(123); n.constructor; // ƒ Number() { [native code] } 一、Object 构造器的成员Object.prototype该属性是所有对象的原型包括 Object对象本身语言中的其他对象正是通过对该属性上添加东西来实现它们之间的继承关系的。所以要小心使用。比如var s new String(若川); Object.prototype.custom 1; console.log(s.custom); // 1 二、Object.prototype 的成员Object.prototype.constructor该属性指向用来构造该函数对象的构造器在这里为Object()Object.prototype.constructor Object; // true var o new Object(); o.constructor Object; // true Object.prototype.toString(radix)该方法返回的是一个用于描述目标对象的字符串。特别地当目标是一个 Number 对象时可以传递一个用于进制数的参数radix该参数radix该参数的默认值为 10。var o {prop:1}; o.toString(); // [object Object] var n new Number(255); n.toString(); // 255 n.toString(16); // ff Object.prototype.toLocaleString()该方法的作用与toString()基本相同只不过它做一些本地化处理。该方法会根据当前对象的不同而被重写例如Date(),Number(),Array(),它们的值都会以本地化的形式输出。当然对于包括Object()在内的其他大多数对象来说该方法与toString()是基本相同的。在浏览器环境下可以通过BOM对象Navigator的language属性在IE中则是userLanguage来了解当前所使用的语言navigator.language; //en-US Object.prototype.valueOf()该方法返回的是用基本类型所表示的this值如果它可以用基本类型表示的话。如果Number对象返回的是它的基本数值而Date对象返回的是一个时间戳timestamp。如果无法用基本数据类型表示该方法会返回this本身。// Object var o {}; typeof o.valueOf(); // object o.valueOf() o; // true // Number var n new Number(101); typeof n; // object typeof n.vauleOf; // function typeof n.valueOf(); // number n.valueOf() n; // false // Date var d new Date(); typeof d.valueOf(); // number d.valueOf(); // 1503146772355 Object.prototype.hasOwnProperty(prop)该方法仅在目标属性为对象自身属性时返回true,而当该属性是从原型链中继承而来或根本不存在时返回false。var o {prop:1}; o.hasOwnProperty(prop); // true o.hasOwnProperty(toString); // false o.hasOwnProperty(formString); // false Object.prototype.isPrototypeOf(obj)如果目标对象是当前对象的原型该方法就会返回true而且当前对象所在原型上的所有对象都能通过该测试并不局限与它的直系关系。var s new String(); Object.prototype.isPrototypeOf(s); // true String.prototype.isPrototypeOf(s); // true Array.prototype.isPrototypeOf(s); // false Object.prototype.propertyIsEnumerable(prop)如果目标属性能在for in循环中被显示出来该方法就返回truevar a [1,2,3]; a.propertyIsEnumerable(length); // false a.propertyIsEnumerable(0); // true 三、在ES5中附加的Object属性在ES3中除了一些内置属性如Math.PI对象的所有的属性在任何时候都可以被修改、插入、删除。在ES5中我们可以设置属性是否可以被改变或是被删除——在这之前它是内置属性的特权。ES5中引入了属性描述符的概念我们可以通过它对所定义的属性有更大的控制权。这些属性描述符特性包括value——当试图获取属性时所返回的值。writable——该属性是否可写。enumerable——该属性在for in循环中是否会被枚举configurable——该属性是否可被删除。set()——该属性的更新操作所调用的函数。get()——获取属性值时所调用的函数。另外数据描述符其中属性为enumerableconfigurablevaluewritable与存取描述符其中属性为enumerableconfigurableset()get()之间是有互斥关系的。在定义了set()和get()之后描述符会认为存取操作已被 定义了其中再定义value和writable会引起错误。以下是ES3风格的属性定义方式var person {}; person.legs 2; 以下是等价的 ES5 通过数据描述符定义属性的方式var person {}; Object.defineProperty(person, legs, {value: 2,writable: true,configurable: true,enumerable: true }); 其中 除了 value 的默认值为undefined以外其他的默认值都为false。这就意味着如果想要通过这一方式定义一个可写的属性必须显示将它们设为true。或者我们也可以通过ES5的存储描述符来定义var person {}; Object.defineProperty(person, legs, {set:function(v) {return this.value v;},get: function(v) {return this.value;},configurable: true,enumerable: true }); person.legs 2; 这样一来多了许多可以用来描述属性的代码如果想要防止别人篡改我们的属性就必须要用到它们。此外也不要忘了浏览器向后兼容ES3方面所做的考虑。例如跟添加Array.prototype属性不一样我们不能在旧版的浏览器中使用shim这一特性。另外我们还可以通过定义nonmalleable属性在具体行为中运用这些描述符var person {}; Object.defineProperty(person, heads, {value: 1}); person.heads 0; // 0 person.heads; // 1 (改不了) delete person.heads; // false person.heads // 1 (删不掉) Object.defineProperty(obj, prop, descriptor) (ES5)具体用法可参见上文或者查看 MDN。MDN Object.defineProperty(obj, descriptor)[4]Vue.js 文档**如何追踪变化**[5] 把一个普通 JavaScript 对象传给 Vue 实例的 data 选项Vue 将遍历此对象所有的属性并使用 Object.defineProperty 把这些属性全部转为 getter/setter。Object.defineProperty 是仅 ES5 支持且无法 shim 的特性这也就是为什么 Vue 不支持 IE8 以及更低版本浏览器的原因。Object.defineProperties(obj, props) (ES5)该方法的作用与defineProperty()基本相同只不过它可以用来一次定义多个属性。比如var glass Object.defineProperties({}, {color: {value: transparent,writable: true},fullness: {value: half,writable: false} }); glass.fullness; // half Object.getPrototypeOf(obj) (ES5)之前在ES3中我们往往需要通过Object.prototype.isPrototypeOf()去猜测某个给定的对象的原型是什么如今在ES5中我们可以直接询问改对象“你的原型是什么”Object.getPrototypeOf([]) Array.prototype; // true Object.getPrototypeOf(Array.prototype) Object.prototype; // true Object.getPrototypeOf(Object.prototype) null; // true Object.create(obj, descr) (ES5)该方法主要用于创建一个新对象并为其设置原型用上述属性描述符来定义对象的原型属性。var parent {hi: Hello}; var o Object.create(parent, {prop: {value: 1} }); o.hi; // Hello // 获得它的原型 Object.getPrototypeOf(parent) Object.prototype; // true 说明parent的原型是Object.prototype Object.getPrototypeOf(o); // {hi: Hello} // 说明o的原型是{hi: Hello} o.hasOwnProperty(hi); // false 说明hi是原型上的 o.hasOwnProperty(prop); // true 说明prop是原型上的自身上的属性。 现在我们甚至可以用它来创建一个完全空白的对象这样的事情在ES3中可是做不到的。var o Object.create(null); typeof o.toString(); // undefined Object.getOwnPropertyDesciptor(obj, property) (ES5)该方法可以让我们详细查看一个属性的定义。甚至可以通过它一窥那些内置的之前不可见的隐藏属性。Object.getOwnPropertyDescriptor(Object.prototype, toString); // {writable: true, enumerable: false, configurable: true, value: ƒ toString()} Object.getOwnPropertyNames(obj) (ES5)该方法返回一个数组其中包含了当前对象所有属性的名称字符串不论它们是否可枚举。当然也可以用Object.keys()来单独返回可枚举的属性。Object.getOwnPropertyNames(Object.prototype); // [__defineGetter__, __defineSetter__, hasOwnProperty, __lookupGetter__, __lookupSetter__, propertyIsEnumerable, toString, valueOf, __proto__, constructor, toLocaleString, isPrototypeOf] Object.keys(Object.prototype); // [] Object.getOwnPropertyNames(Object); // [length, name, arguments, caller, prototype, assign, getOwnPropertyDescriptor, getOwnPropertyDescriptors, getOwnPropertyNames, getOwnPropertySymbols, is, preventExtensions, seal, create, defineProperties, defineProperty, freeze, getPrototypeOf, setPrototypeOf, isExtensible, isFrozen, isSealed, keys, entries, values] Object.keys(Object); // [] Object.preventExtensions(obj) (ES5)Object.isExtensible(obj) (ES5)preventExtensions()方法用于禁止向某一对象添加更多属性而isExtensible()方法则用于检查某对象是否还可以被添加属性。var deadline {}; Object.isExtensible(deadline); // true deadline.date yesterday; // yesterday Object.preventExtensions(deadline); Object.isExtensible(deadline); // false deadline.date today; deadline.date; // today // 尽管向某个不可扩展的对象中添加属性不算是一个错误操作但它没有任何作用。 deadline.report true; deadline.report; // undefined Object.seal(obj) (ES5)Object.isSeal(obj) (ES5)seal()方法可以让一个对象密封并返回被密封后的对象。seal()方法的作用与preventExtensions()基本相同但除此之外它还会将现有属性 设置成不可配置。也就是说在这种情况下我们只能变更现有属性的值但不能删除或用defineProperty()重新配置这些属性例如不能将一个可枚举的属性改成不可枚举。var person {legs:2}; // person Object.seal(person); // true Object.isSealed(person); // true Object.getOwnPropertyDescriptor(person, legs); // {value: 2, writable: true, enumerable: true, configurable: false} delete person.legs; // false (不可删除不可配置) Object.defineProperty(person, legs,{value:2}); person.legs; // 2 person.legs 1; person.legs; // 1 (可写) Object.defineProperty(person, legs, { get: function() { return legs; } }); // 抛出TypeError异常 Object.freeze(obj) (ES5)Object.isFrozen(obj) (ES5)freeze()方法用于执行一切不受seal()方法限制的属性值变更。Object.freeze() 方法可以冻结一个对象冻结指的是不能向这个对象添加新的属性不能修改其已有属性的值不能删除已有属性以及不能修改该对象已有属性的可枚举性、可配置性、可写性。也就是说这个对象永远是不可变的。该方法返回被冻结的对象。var deadline Object.freeze({date: yesterday}); deadline.date tomorrow; deadline.excuse lame; deadline.date; // yesterday deadline.excuse; // undefined Object.isSealed(deadline); // true; Object.isFrozen(deadline); // true Object.getOwnPropertyDescriptor(deadline, date); // {value: yesterday, writable: false, enumerable: true, configurable: false} (不可配置不可写) Object.keys(deadline); // [date] (可枚举) Object.keys(obj) (ES5)该方法是一种特殊的for-in循环。它只返回当前对象的属性不像for-in而且这些属性也必须是可枚举的这点和Object.getOwnPropertyNames()不同不论是否可以枚举。返回值是一个字符串数组。Object.prototype.customProto 101; Object.getOwnPropertyNames(Object.prototype); // [..., constructor, toLocaleString, isPrototypeOf, customProto] Object.keys(Object.prototype); // [customProto] var o {own: 202}; o.customProto; // 101 Object.keys(o); // [own] 四、在ES6中附加的Object属性Object.is(value1, value2) (ES6)该方法用来比较两个值是否严格相等。它与严格比较运算符的行为基本一致。不同之处只有两个一是0不等于-0而是NaN等于自身。Object.is(若川, 若川); // true Object.is({},{}); // false Object.is(0, -0); // false 0 -0; // true Object.is(NaN, NaN); // true NaN NaN; // false ES5可以通过以下代码部署Object.isObject.defineProperty(Object, is, {value: function() {x, y} {if (x y) {// 针对0不等于-0的情况return x ! 0 || 1 / x 1 / y;}// 针对 NaN的情况return x ! x y ! y;},configurable: true,enumerable: false,writable: true }); Object.assign(target, ...sources) (ES6)该方法用来源对象source的所有可枚举的属性复制到目标对象target。它至少需要两个对象作为参数第一个参数是目标对象target后面的参数都是源对象source。只有一个参数不是对象就会抛出TypeError错误。var target {a: 1}; var source1 {b: 2}; var source2 {c: 3}; obj Object.assign(target, source1, source2); target; // {a:1,b:2,c:3} obj; // {a:1,b:2,c:3} target obj; // true // 如果目标对象与源对象有同名属性或多个源对象有同名属性则后面的属性会覆盖前面的属性。 var source3 {a:2,b:3,c:4}; Object.assign(target, source3); target; // {a:2,b:3,c:4} Object.assign只复制自身属性不可枚举的属性enumerable为false和继承的属性不会被复制。Object.assign({b: c},Object.defineProperty({}, invisible, {enumerable: false,value: hello}) ); // {b: c} 属性名为Symbol值的属性也会被Object.assign()复制。Object.assign({a: b}, {[Symbol(c)]: d}); // {a: b, Symbol(c): d} 对于嵌套的对象Object.assign()的处理方法是替换而不是添加。Object.assign({a: {b:c,d:e}}, {a:{b:hello}}); // {a: {b:hello}} 对于数组Object.assign()把数组视为属性名为 0、1、2 的对象。Object.assign([1,2,3], [4,5]); // [4,5,3] Object.getOwnPropertySymbols(obj) (ES6)该方法会返回一个数组该数组包含了指定对象自身的非继承的所有 symbol 属性键。该方法和 Object.getOwnPropertyNames() 类似但后者返回的结果只会包含字符串类型的属性键也就是传统的属性名。Object.getOwnPropertySymbols({a: b, [Symbol(c)]: d}); // [Symbol(c)] Object.setPrototypeOf(obj, prototype) (ES6)该方法设置一个指定的对象的原型 ( 即, 内部[[Prototype]]属性到另一个对象或 null。__proto__属性用来读取或设置当前对象的prototype对象。目前所有浏览器包括IE11都部署了这个属性。// ES6写法 var obj {method: function(){// code ...} }; // obj.__proto__ someOtherObj; // ES5写法 var obj Object.create(someOtherObj); obj.method function(){// code ... }; 该属性没有写入ES6的正文而是写入了附录。__proto__前后的双下划线说明它本质上是一个内部属性而不是正式对外的一个 API。无论从语义的角度还是从兼容性的角度都不要使用这个属性。而是使用Object.setPrototypeOf()写操作Object.getPrototypeOf()读操作或Object.create()生成操作代替。在实现上__proto__调用的Object.prototype.__proto__。Object.setPrototypeOf()方法的作用与__proto__作用相同用于设置一个对象的prototype对象。它是ES6正式推荐的设置原型对象的方法。五、在ES8中附加的Object属性Object.getOwnPropertyDescriptors(obj) (ES8)该方法基本与Object.getOwnPropertyDescriptor(obj, property)用法一致只不过它可以用来获取一个对象的所有自身属性的描述符。Object.getOwnPropertyDescriptor(Object.prototype, toString); // {writable: true, enumerable: false, configurable: true, value: ƒ toString()} Object.getOwnPropertyDescriptors(Object.prototype); // 可以自行在浏览器控制台查看效果。 Object.values(obj) (ES8)Object.values() 方法与Object.keys类似。返回一个给定对象自己的所有可枚举属性值的数组值的顺序与使用for...in循环的顺序相同 ( 区别在于for-in循环枚举原型链中的属性 )。var obj {a:1,b:2,c:3}; Object.keys(obj); // [a,b,c] Object.values(obj); // [1,2,3] Object.entries(obj) (ES8)Object.entries() 方法返回一个给定对象自己的可枚举属性[keyvalue]对的数组数组中键值对的排列顺序和使用 for...in 循环遍历该对象时返回的顺序一致区别在于一个for-in循环也枚举原型链中的属性。var obj {a:1,b:2,c:3}; Object.keys(obj); // [a,b,c] Object.values(obj); // [1,2,3] Object.entries(obj); // [[a,1],[b,2],[c,3]] 六、在ES10中附加的Object属性Object.fromEntries(iterable) (ES10)Object.fromEntries()方法返回一个给定可迭代对象类似Array、Map或其他可迭代对象对应属性的新对象。Object.fromEntries() 是 Object.entries()的逆操作。var arr [[a,1],[b,2],[c,3]]; Object.fromEntries(obj); // {a: 1, b: 2, c: 3} var entries new Map([[name, 若川],[age, 18] ]); Object.fromEntries(entries) // {name: 若川, age: 18} 小结细心的读者可能会发现MDN上还有一些API本文没有列举到。因为那些是非标准的API。熟悉对象的 API 对理解原型和原型链相关知识会有一定帮助。常用的 API 主要有Object.prototype.toString()Object.prototype.hasOwnProperty() Object.getPrototypeOf(obj)Object.create()Object.definePropertyObject.keys(obj)Object.assign()。如果读者发现有不妥或可改善之处再或者哪里没写明白的地方欢迎评论指出。另外觉得写得不错对您有些许帮助可以点赞、评论、转发分享也是对笔者的一种支持非常感谢呀。参考资料MDN Object API[6]JavaScript 面向对象编程指南第 2 版豆瓣读书链接[7]阮一峰 ES6 标准入门 2[8]原创精选文章工作一年后我有些感悟(写于2017年)高考七年后、工作三年后的感悟面试官问JS的继承前端使用puppeteer 爬虫生成《React.js 小书》PDF并合并学习 jQuery 源码整体架构打造属于自己的 js 类库学习underscore源码整体架构打造属于自己的函数式编程类库学习 lodash 源码整体架构打造属于自己的函数式编程类库学习 sentry 源码整体架构打造属于自己的前端异常监控SDK学习 vuex 源码整体架构打造属于自己的状态管理库学习 axios 源码整体架构打造属于自己的请求库知乎问答一年内的前端看不懂前端框架源码怎么办微信公众号作者常以若川为名混迹于江湖。前端路上 | PPT 爱好者 | 所知甚少唯善学。博客https://lxchuan12.cn/posts/阅读体验可能更好些。若川视野主要发布前端 | PPT | 生活 | 效率相关的文章长按扫码关注。欢迎加我微信lxchuan12注明来源基本来者不拒拉您进【前端视野交流群】长期交流学习~参考资料[1]vue-router 源码里就是类似这样写的: https://github.com/vuejs/vue-router/blob/dev/src/install.js#L38-L44[2]【深度长文】JavaScript数组所有API全解密: http://louiszhai.github.io/2017/04/28/array/[3]JavaScript字符串所有API全解密: http://louiszhai.github.io/2016/01/12/js.String/[4]MDN Object.defineProperty(obj, descriptor): https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty[5]如何追踪变化: https://cn.vuejs.org/v2/guide/reactivity.html[6]MDN Object API: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object[7]JavaScript面向对象编程指南第2版豆瓣读书链接: https://book.douban.com/subject/26302623/[8]阮一峰 ES6标准入门2: http://es6.ruanyifeng.com/由于公众号限制外链点击阅读原文或许阅读体验更佳觉得文章不错可以点个在看呀^_^
http://www.pierceye.com/news/187625/

相关文章:

  • 怎么做网站报告四平网站公司
  • 飞扬动力网站建设支付网站建设要求
  • 达美网站建设廊坊seo扣费
  • 好享购物官方网站购物网页制作与网站开发从入门到精通
  • 坪山网站建设哪家便宜系部网站建设研究方案
  • 如何备份网站上海的招聘网站有哪些
  • 企业门户网站建设流程蝶恋花直播app下载安装
  • 株洲网站建设推广报价seo基础知识培训视频
  • 漳州网站建设选博大不错php网站开发经理招聘
  • 分类网站建设黄陌陌网站怎么做
  • 做网站大概多钱互联网广告投放
  • 信通网站开发中心qq说说赞在线自助下单网站
  • 搭建网站步骤做电影网站需要什么条件
  • 您网站建设动漫设计与制作 学校
  • 利用模板如何制作网站泰安整站优化
  • 网站开发与网站建设网站上的聊天框怎么做的
  • 任务网站(做任务学技能的)开发公司宣传册
  • 织梦搭建商城网站高端网站建设深圳
  • 做网站排名优化的公司无需下载直接登录qq手机版
  • 网站不备案不能访问吗wordpress主题开发404页面
  • 工作总结个人总结自动app优化下载
  • 网站开发推荐书籍比较大的外贸网站
  • 上饶建设网站郑州网
  • 做淘宝客网站一定要备案吗没有网站域名备案
  • 用QQ群做网站排名慈溪网站制作哪家最好
  • 兴宁市网站建设手工艺品网站建设策划书
  • flash做网站导航网站品牌建设流程
  • 公司建设网站属于什么费用网站打模块
  • 网站建设应注意的问题网站备案验证码错误
  • 网站核验点网站自己怎么做的