Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

重学js —— 函数:箭头函数定义和方法定义(包含get/set) #83

Open
lizhongzhen11 opened this issue Mar 7, 2020 · 0 comments
Labels
js基础 Good for newcomers 重学js 重学js系列 规范+MDN

Comments

@lizhongzhen11
Copy link
Owner

lizhongzhen11 commented Mar 7, 2020

函数:箭头函数定义和方法定义(包含get/set)

箭头函数求值

  • 箭头函数没有自己的 thisargumentssupernew.target
  • 箭头函数不能做构造器,不能被 new 调用
  • 箭头函数没有 prototype 属性
  • 使用 bindcallapply 调用时,第一个参数会被忽略
  • 不能使用 yield 命令,所以不能作为 Generator 函数
let arrow = (...args) => console.log(...args)
console.log(arrow.prototype) // undefined
arrow.call(1, 2, 3) // 2 3
new arrow // TypeError: arrow is not a constructor

// 来自高级前端面试,我错了
const getList = ([x, ...y]) => [x, y]
const getUser = user => { name: user.name, age: user.age }
const list = [1, 2, 3, 4]
const user = {name: 'lizz', age: 28}

console.log(getList(list))
console.log(getUser(user))

// 这里 getUser 很容易迷惑人,事实上控制台直接报错了
// 这里花括号会被解析为函数体的花括号,而不是对象

箭头函数 : 箭头参数 => 简洁体

  1. 定义 scope运行时执行上下文LexicalEnvironment
  2. 定义 parameters 为箭头参数的 CoveredFormalsList
  3. 定义 closureOrdinaryFunctionCreate(%Function.prototype%, parameters, 简洁体, lexical-this, scope)
  4. closure.[[SourceText]] 赋值为由箭头函数匹配的 源文本
  5. 返回 closure

注意:箭头函数不会定义 argumentssuperthisnew.target 的基础绑定。箭头函数内任何对 argumentssuperthisnew.target 的引用必须解析为词法包围环境中的绑定。通常是一个立即封闭函数的函数环境。即使箭头函数可能包含对 super 的引用,通过执行 MakeMethod 不能将第3步创建的 函数对象 变成方法。引用 super 的箭头函数始终包含在非箭头函数中,可通过箭头函数的函数对象捕获的 scope 访问实现 super 的必要状态。

表达式体 : 赋值表达式

  1. 定义 exprRef 为赋值表达式求值
  2. 定义 exprValue ? GetValue(exprRef)
  3. 返回 Completion{ [[Type]]: return, [[Value]]: exprValue, [[Target]]: empty }

方法定义(包含get/set)

  • getter
  • setter
  • MDN —— 方法的定义
  • get 语法不能带参数,如果是对象属性调用,不需要括号,可被 delete 删除
  • set 语法必须有一个明确的参数,像正常对象属性赋值那样调用即可,可被 delete 删除
// get
let obj = {
  name: 'test',
  get objName() { // 不能带参数
    return this.name
  }
}
obj.objName // 'test' 注意这里获取,不需要括号
var expr = 'foo';
var obj = {
  get [expr]() { return 'bar'; }
};
console.log(obj.foo); // "bar"

// set
var language = {
  set current(name) {
    this.log.push(name);
  },
  log: []
}
language.current = 'EN';
console.log(language.log); // ['EN']
language.current = 'FA';
console.log(language.log); // ['EN', 'FA']

// set返回undefined,来自高级前端面试选择题
const config = {
  languages: [ ],
  set language(lang) {
    return this.languages.push(lang)
  }
}
console.log(config.language)

A. function language(lang) { this.languages.push(lang) }
B. 0
C. [ ]
D. undefined

DefineMethod

伴有参数 objectfunctionPrototype

方法定义 : 属性名 ( 唯一的形参 ) { 函数体 }

  1. 定义 propKey属性名 求值结果
  2. ReturnIfAbrupt(propKey)
  3. 定义 scope运行时执行上下文LexicalEnvironment
  4. 如果 functionPrototype 作为参数存在,
    1. 定义 prototypefunctionPrototype
  5. 否则,
    1. 定义 prototype%Function.prototype%
  6. 定义 closureOrdinaryFunctionCreate(prototype, 唯一的形参, 函数体, non-lexical-this, scope)
  7. 执行 MakeMethod(closure, object)
  8. closure.[[SourceText]] 赋值为由 方法定义 匹配的 源文本
  9. 返回 记录 { [[Key]]: propKey, [[Closure]]: closure }

PropertyDefinitionEvaluation

伴有参数 objectenumerable

方法定义 : 属性名 ( 唯一的形参 ) { 函数体 }

  1. 定义 methodDef 为 参数是 object方法定义? DefineMethod
  2. 执行 SetFunctionName(methodDef.[[Closure]], methodDef.[[Key]])
  3. 定义 desc 属性描述符 { [[Value]]: methodDef.[[Closure]], [[Writable]]: true, [[Enumerable]]: enumerable, [[Configurable]]: true }
  4. 返回 ? DefinePropertyOrThrow(object, methodDef.[[Key]], desc)

方法定义 : get 属性名 () { 函数体 }

  1. 定义 propKey属性名 求值结果
  2. ReturnIfAbrupt(propKey)
  3. 定义 scope运行时执行上下文LexicalEnvironment
  4. 定义 formalParameterList形参 : [empty] 的实例
  5. 定义 closureOrdinaryFunctionCreate(%Function.prototype%, formalParameterList, 函数体, non-lexical-this, scope)
  6. 执行 MakeMethod(closure, object)
  7. 执行 SetFunctionName(closure, propKey, "get")
  8. closure.[[SourceText]] 赋值为由 方法定义 匹配的 源文本
  9. 定义 desc 属性描述符 { [[Get]]: closure, [[Enumerable]]: enumerable, [[Configurable]]: true }
  10. 返回 ? DefinePropertyOrThrow(object, propKey, desc)

方法定义 : set 属性名 ( 属性参数列表 ) { 函数体 }

  1. 定义 propKey属性名 求值结果
  2. ReturnIfAbrupt(propKey)
  3. 定义 scope运行时执行上下文LexicalEnvironment
  4. 定义 closureOrdinaryFunctionCreate(%Function.prototype%, 属性参数列表, 函数体, non-lexical-this, scope)
  5. 执行 MakeMethod(closure, object)
  6. 执行 SetFunctionName(closure, propKey, "set")
  7. closure.[[SourceText]] 赋值为由 方法定义 匹配的 源文本
  8. 定义 desc 属性描述符 { [[Set]]: closure, [[Enumerable]]: enumerable, [[Configurable]]: true }
  9. 返回 ? DefinePropertyOrThrow(object, propKey, desc)

2020-03-25 补充

// 来自高级前端面试,这题我做对了,但是还是写下来
var status = 'a'

setTimeout(() => {
  const status = 'b'

  const data = {
    status: '',
    getStatus() {
      return this.status
    }
  }

  console.log(data.getStatus())
  console.log(data.getStatus.call(this))
}, 0)

// 选B,这里是箭头函数
A. '' and 'b'
B. '' and 'a'
C. 'b' and 'a'
D. 'a' and 'a'

2020-04-05 补充

// 来自高级前端面试,这题我选错了,fuck
const add = x => y => z => {
  console.log(x, y, z);
  return x + y + z;
}
add(4)(5)(6) // 选 A

A. 4 5 6
B. 6 5 4
C. 4 function function
D. undefined undefined 6
@lizhongzhen11 lizhongzhen11 added js基础 Good for newcomers 重学js 重学js系列 规范+MDN labels Mar 7, 2020
This was referenced Mar 7, 2020
@lizhongzhen11 lizhongzhen11 changed the title 重学js —— 函数和类:箭头函数定义和方法定义(包含get/set) 重学js —— 函数:箭头函数定义和方法定义(包含get/set) Mar 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
js基础 Good for newcomers 重学js 重学js系列 规范+MDN
Projects
None yet
Development

No branches or pull requests

1 participant