在有 Vue Router 的项目中如何在 Object 原型上增加方法

news/2024/7/9 23:40:02 标签: vue, vue-router, prototype, Object, defineProperty

现象

在有 Vue Router 的项目开发过程中,在 Object.prototype 上挂自定义方法,会发现它的函数体内容会被拼接到 url 参数里。(下面以 Object.prototype.log 为例)

import Vue from 'vue'
import App from './App'
import router from './router'
// 在 Object.prototype 上挂了一个方法
Object.prototype.log = function() {
  console.log(this)
}
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

在这里插入图片描述

原因

1. 定位 Vue Router 上的 for-in

初步怀疑是某个操作遍历到了 Object.prototype.log;和 url 有关那么很可能在 Vue Router 中。在这两点猜测下,定位到 Vue Router 的 query.js 的一个 resolveQuery 函数:

export function resolveQuery (
  query: ?string,
  extraQuery: Dictionary<string> = {},
  _parseQuery: ?Function
): Dictionary<string> {
  const parse = _parseQuery || parseQuery
  let parsedQuery
  try {
    parsedQuery = parse(query || '')
  } catch (e) {
    process.env.NODE_ENV !== 'production' && warn(false, e.message)
    parsedQuery = {}
  }
  // 问题出在 for-in 的遍历中,遍历到了 log 函数
  for (const key in extraQuery) {
    parsedQuery[key] = extraQuery[key]
  }
  return parsedQuery
}

然后在 router.js 中经过 createRoute 函数中的 stringifyQuery 操作,拼接到最终的 url 上。
在这里插入图片描述
在这里插入图片描述

2. for-in 遍历方式

Object.prototype 上有 toString 等方法,为什么它不会被遍历到呢?for-in 的遍历方式如下:

for…in语句以任意顺序遍历一个对象自有的、继承的、可枚举的、非Symbol的属性。对于每个不同的属性,语句都会被执行。

通过 Object.prototype.propertyIsEnumerable 方法可以判断出 log 方法是一个可枚举的属性,所以会被 for-in 遍历到。
在这里插入图片描述

解决方法

把定义的方法变成不可枚举就行,需要借助 Object.defineProperty,可以解决上述问题

import Vue from 'vue'
import App from './App'
import router from './router'
/*// 在 Object.prototype 上挂了一个方法
Object.prototype.log = function() {
  console.log(this)
}*/
// 改成 Object.defineProperty 的方法
Object.defineProperty(Object.prototype, 'log', {
  // enumerable: false,		// 设置为不可枚举,默认值已为 false
  // configurable、writable 等根据需要设置
  value: function() {
    console.log(this)
  }
})
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

更多

尽量不要改任何 builtin 对象的 prototype,尤其是修改 Object.prototype。因为即使不用 Vue Router,即使不是在 vue 项目中,在任何地方,只要对任何对象执行了 for-in 操作,都会可能引入不想要的内容。

其实不应该通过 prototype 来增加方法,最好是通过外置公共方法,例如上面应该改成 export function log(obj) { console.log(obj) }


http://www.niftyadmin.cn/n/1436947.html

相关文章

mysql最大值,最小值,总和查询与计数查询

1、最大值查询: mysql> select max(score) from 4a; +------------+ | max(score) | +------------+ | 93 | +------------+ 1 row in set (0.06 sec) 2、最小值查询: mysql> select max(4a.score),min(4inall.score) from 4a,4inall; +---------------+---…

多个数的最大公约数、最小公倍数算法

首先&#xff0c;笔者假设大家已经会辗转相除法和更相减损术。 两个数的最大公约数&#xff08;GCD&#xff09;、最小公倍数&#xff08;LCM&#xff09;用上面两个算法实现非常简单。那么如果是同时求多个数的呢&#xff1f; 首先约定两个数的最大公约数的函数为gcd&#x…

mysql加减乘除,求余,求平均值,查询不等于某数值

1.mysql加减乘除操作: mysql> select score,score+5,score-5,score*5,score/5 from 4a; +-------+---------+---------+---------+---------+ | score | score+5 | score-5 | score*5 | score/5 | +-------+---------+---------+---------+---------+ | 93 | 98 |…

egg-shell-decorators结合egg-jwt实现token验证

在 egg.js 搭建服务端框架过程中&#xff0c;我使用了装饰器 egg-shell-decorators 来简化我的 controller 配置 router&#xff0c;同时用了 egg-jwt 来进行身份验证&#xff0c;按照其文档的配置过程之后&#xff0c;我还是遇到了坑。 如果你使用了 egg-jwt&#xff0c;那默认…

tomcat安装ssl证书Connector attribute SSLCertificateFile must be defined when using SSL with APR

其实网上有很多安装的教程&#xff0c;这里简单放一些参考链接&#xff1a; https://cloud.tencent.com/document/product/400/35224 但应该有很多人和我一样&#xff0c;按照教程改了 tomcat 的 server.xml 后&#xff0c;启动是报错 Connector attribute SSLCertificateFile…

mysql中条件限制语句(一)where in and

1.between语句: mysql> select * from 4a where score between 76 and 89; +--------+------+--------+------+--------+------+------+-------+ | sname | sage | tname | t | cname | s | c | score | +--------+------+--------+------+--------+------+---…

mysql中条件限制语句(二)like 全匹配 全模糊 distinct limit

5.limit语句: 语法:select 字段名 from 标明 limit 起始行,查询几行; mysql> select * from 4a limit 0,3; +--------+------+--------+------+--------+------+------+-------+ | sname | sage | tname | t | cname | s | c | score | +--------+------+---…

Warning: no saslprep library specified. Passwords will not be sanitized

在 nodejs 中使用密码连接 mongodb 时&#xff0c;会报 warning&#xff1a; Warning: no saslprep library specified. Passwords will not be sanitized在 mongodb 的依赖里 node_modules/mongodb/lib/core/auth/scram.js 发现有以下代码&#xff1a; 12&#xff1a; let s…