js 定义属性奇怪的问题。

2016-03-20 14:48:32 +08:00
 cc7756789
function Keygrip(keys) {
  if (arguments.length > 1) {
    console.warn('as of v2, keygrip() only accepts a single argument.')
    console.warn('set keygrip().hash= instead.')
    console.warn('keygrip() also now only supports buffers.')
  }

  if (!Array.isArray(keys) || !keys.length) throw new Error("Keys must be provided.")
  if (!(this instanceof Keygrip)) return new Keygrip(keys)

  this.keys = keys
}


 Keygrip.prototype = {
  _hash: 'sha256',
}


Object.defineProperties(Keygrip.prototype, {
  // modified Keygrip.prototype.constructor's enumerable = false
  constructor: {
    value: Keygrip,
    writable: true,
    configurable: true
  },
  
  hash: {
    get: () => {
      console.log(this);  // {} 空对象
      return this._hash;  // undefined
    },
    set: (val) => {
      if (!util.supportedHash(val)) throw new Error('unsupported hash algorithm: ' + val);
      this._hash = val;   
    }
  },
 
});

>>> const KeyGrip = require('keygrip');
>>> var s = KeyGrip(['fuck off my house', 'I never want to see you again']);
>>> console.log(s.hash)
{}
undefined

这是keygrip模块,我看到它原本的 constructor 只是定义了 value ,是可枚举的。手贱 fork 后修改了下,发现 get 和 set 中的 this 都是指向了一个空对象{},所以这样写的话,无论获取还是设置,都没有成功,想不明白到底是为什么。

2902 次点击
所在节点    JavaScript
9 条回复
ETiV
2016-03-20 14:52:49 +08:00
我擦,吓到宝宝了,居然有代码加色
ggiiss
2016-03-20 15:31:01 +08:00
目测是 箭头函数的坑,
解决方法是:不用箭头函数
cc7756789
2016-03-20 15:36:57 +08:00
@ggiiss 我去我一着急,就一路用箭头装逼下去,现在一换过来,果然,这个坑搞得我测试了很长时间,一路以为是作用域的问题
ggiiss
2016-03-20 15:42:21 +08:00
@cc7756789 es6 增加了 let, => 特性后我发现之前的作用域, this 指向 问题又复杂了,泪。
Wenwei
2016-03-20 17:51:32 +08:00
你这箭头函数用错了。

```javascript
hash: {
get() {
console.log(this); // {} 空对象
return this._hash; // undefined
},
set(val) {
if (!util.supportedHash(val)) throw new Error('unsupported hash algorithm: ' + val);
this._hash = val;
}
},
```
haozhang
2016-03-20 19:18:09 +08:00
arrow function 的 this 是来自外部域的,你调用 xxx.hash = yyy 的时候,是调用了 set 函数,但是 set 箭头函数中的 this 并不指向 xxx ,而是指向 xxx.hash = yyy 这个语句所在域的 this 。我估计这个域是个最外层域,所以 this 就变成了 undefined , get 同理。这是我的推断不知道对不对。
cc7756789
2016-03-21 08:14:09 +08:00
@haozhang 是的,我用 arraw 的时候没有去看 es6 ,以为和普通的匿名函数是一样的,后来才知道 es6 的 arraw 的作用域只会是调用方法的对象,而没有运行时这个坑,之所以只在 arraw 规则这样实现,我认为是为了做到向后兼容吧,普通的函数 this 运行时依旧不改变。
morethansean
2016-03-21 09:13:13 +08:00
@cc7756789 “之所以……” function 里的 this 本来就是语言的特性之一,谈不上什么向后兼容。
acthtml
2016-04-07 14:33:23 +08:00
keygrip 这个模块看不懂有什么用,

只是做一个 hash 加密的话,为何参数要设置成数组,直接指定一个字符串作为秘钥不就行了。

不明白。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/264920

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX