You Dont Know JS(上)笔记

最近项目,一直在研究使用新的框架,新的工具,结果发现学习的速度还没有轮子出现的速度快,就拿webpack来说,1.0都还没有掌握,2.0就出来了,无力感突现,一直在跟随着别人的脚步在前进,都没有自己的东西,所以内功才是一切,内功强大,自己写一个框架,也不是不可。不然你连人家的源码都不懂,只会用又有什么用呢,明天换一个框架,或者换一个公司,你又要从头开始,你的竞争力又在何方。

  • 作用域

1,LHS(赋值操作)和RHS(取值操作)查询都会在当前执行作用域开始,如果没有找到,就会向上级作用域继续查找目标标识符,这样每次上升一级,最后抵达全局作用域。
2,不成功的RHS引用会抛出ReferenceError异常,不成功的LHS引用会导致自动隐式的创建全局变量(非严格模式下),或者抛出ReferenceError异常(严格模式下)
  • 词法作用域##

词法作用域完全由写代码期间函数声明的位置来定义

function foo(a) {
    var b = a * 2;
    function bar(c) {
        console.log( a, b, c );
    }

    bar(b * 3);
}
foo( 2 ); // 2 4 12

对于console而言,会先查找最内部的作用域,引擎在这里无法找到a,因此就会去上一层作用域中查找。作用域查找会在找到第一个匹配的标识符时停止,所以在多层嵌套的作用域中可以定义同名的标识符,这叫做遮蔽效应(内部的标识符遮蔽了外部的标识符)

function foo(str, a) {
    eval( str ); // 欺骗!,在运行时就相当于var b= 3,遮蔽了外部的b
    // 但是在严格模式下,eval运行时,有自己的作用域,无法修改所在的作用域
    console.log( a, b );
}
var b = 2;
foo( "var b = 3;", 1 ); // 1 3
function foo(obj) {
    with (obj) {
        a = 2;
    }
}
var o1 = {
    a: 3
};
var o2 = {
    b: 3
};
foo( o1 );
console.log( o1.a ); // 2
foo( o2 );
console.log( o2.a ); // undefined
console.log( a ); // 2 -- 不好,a被泄露到全局作用域上了!
//当我们传递o1给with时,with所声明的作用域是o1,而这个作用域中含有一个相符的标识符,但是我们将o2作为作用域时,其中并没有a标识符,因此进行了正常的LHS查找

使用eval和with可以欺骗词法作用域,但是会导致性能的下降,所以不要使用,同时因为js引擎会在编译阶段进行数项的优化,但是对于未知的代码时优化不了的

  • 函数作用域和块作用域

1,在软件设计中,应该最小限度的暴露必要内容,而将其他的内容都隐藏起来,比如某个模块或对象的API,
2,(function(){})()和(function(){}())是一样的东西,都叫做立即执行函数表达式(IIFE),看个人习惯,
3,在try/catch的catch分局中会创建一个作用域
4,
  • 提升

1,js存在预编译阶段,此时会将函数声明和变量提升,并且函数会在变量之前,同事若是重复的声明将会忽略
  • 闭包

1,无论通过何种手段将内部函数传递到所在的词法作用域以外,他都会持有对原始定义作用域的引用,无论在何处执行这个函数都会使用闭包,内部的变量都不会销毁,因为闭包需要使用,最常见的就是回调函数,和setTimeout,
2,延迟函数的回调会在循环结束后才执行,会先把当前的同步执行完,
3,现在大多数的模块依赖加载/管理器的本质上都是将这种模块定义封装进一个友好的API中,一下是核心的原理
var MyModules = (function Manager(){
  var modules = []
  // name: 模块名称
  // deps:模块依赖
  // impl: 模块实体
  function define(name,deps,impl){
    // 得到所有依赖,当前依赖的东西必须在之前已经定义好的
    for(var i=0;i<deps.length;i++){
      deps[i] = modules[deps[i]]
    }
    // 定义模块,将所有依赖传入当前的模块实体中,这样模块便可以使用依赖
    // apply会直接执行函数,然后得到模块暴露出来的API
    modules[name] = impl.apply(impl,deps)
  }
  
  function get(name){
    return modules[name]
  }
  
  // 暴露API
  return {
    define: define,
    get: get
  }
})()
4,模块文件中的内容会被当做好像包含在作用域闭包中一样来处理。
  • this

使用new来调用函数,会自动执行下面的操作
1,创建一个全新的对象
2,这个对象会被执行[[Prototype]]连接
3,这个新对象会绑定到函数调用的this
4,如果函数内部没有返回,那么自动返回这个新对象
1,字符串,数值,布尔字面量在需要的时候会自动转换为对应的对象
2,object.assign使用=复制,所以引用的东西复制过来还是引用
3,var myobject  = Object.create(anotherobject)//以这个对象为原型创建一个对象
var obj = Object.create(null)得到的对象没有_proto_,存储数据最好了。
  • 原型,委托

这里的原型概念确实拓展了以前的理解
常见的类的实现

function Foo(who){
    this.me = who
}
Foo.prototype.identify = function(){
    return 'I am '+ this.me
}
function Bar(who){
    Foo.call(this,who)
}
// 惭愧,以前直接=,因为是引用,所以不合逻辑
Bar.prototype = Object.create(Foo.prototype)
Bar.prototype.speak = function(){
    alert('Hello,'+ this.identify()+'.')
}
var b1 = new Bar('b1')
var b2 = new Bar('b2')
b1.speak()
b2.speak()

这种实现情况下,他的关系图如下(良心出品):

传统实现关系图.png

1,因为bar的原型对象中没有constructor所以去原型链中找到了Foo,b1,b2也是一样
2,Foo,Bar都是Function 的一个实例(函数也是一个对象),包括function Object()也是,所以他们的constructor都指向Function 对象,而proto都指向Function.prototype,

使用委托风格实现的代码:

Foo = {
  init: function(who){
    this.me = who
  },
  identify: function(){
    return 'I am '+this.me
  }
}

Bar = Object.create(Foo)

Bar.speak = function(){
  alert('Hello,'+this.identify()+'.')
}

var b1 = Object.create(Bar)
b1.init('b1')

var b2 = Object.create(Bar)
b2.init('b2')

b1.speak()
b2.speak()

关系图如下:


委托实现关系图.png

实现方式比较简单,就是一路的使用原型链去委托,找不到的话,就去上一级寻找。
还是习惯于使用传统的方式,但是委托的方式还是很大拓展的思维

  • 严格模式的限制

变量必须声明后再使用
函数的参数不能有同名属性,否则报错
不能使用with语句
不能对只读属性赋值,否则报错
不能使用前缀0表示八进制数,否则报错
不能删除不可删除的属性,否则报错
不能删除变量delete prop,会报错,只能删除属性delete global[prop]
eval不会在它的外层作用域引入变量
eval和arguments不能被重新赋值
arguments不会自动反映函数参数的变化
不能使用arguments.callee
不能使用arguments.caller
禁止this指向全局对象
不能使用fn.caller和fn.arguments获取函数调用的堆栈
增加了保留字(比如protected、static和interface)
  • es6模块

1,代码是在模块作用域之中运行,而不是在全局作用域运行。模块内部的顶层变量,外部不可见。
2,模块脚本自动采用严格模式,不管有没有声明use strict。
3,模块之中,可以使用import命令加载其他模块(.js后缀不可省略,需要提供绝对 URL 或相对 URL),也可以使用export命令输出对外接口。
4,模块之中,顶层的this关键字返回undefined,而不是指向window。也就是说,在模块顶层使用this关键字,是无意义的。
5,同一个模块如果加载多次,将只执行一次。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,596评论 18 139
  • 官方中文版原文链接 感谢社区中各位的大力支持,译者再次奉上一点点福利:阿里云产品券,享受所有官网优惠,并抽取幸运大...
    HetfieldJoe阅读 3,650评论 2 27
  • 第一章 编译原理 js是一门编译语言 传统编译语言流程: 分词/词法分析:把字符串分解成有意义的代码块 解析/语法...
    冥冥2017阅读 582评论 0 0
  • 前言 人生苦多,快来 Kotlin ,快速学习Kotlin! 什么是Kotlin? Kotlin 是种静态类型编程...
    任半生嚣狂阅读 26,142评论 9 118
  • 241、我希望所有的单身,都是一种勇者的自信与诚实,所有的婚姻,都是一种强者的风花与雪月。 242、女人一生中的精...
    夏烟阅读 338评论 1 3