不JS上

作用域

  • 作用域是一套用来管理引擎如何在当前作用域以及嵌套的子作用域中根据标示符名称进性变量查找的规则。
  • 引擎会为出现在赋值操作左侧的变量进行LHS查询,其余的执行RHS查询。当执行LHS查询时,如果直到在全局作用域也找不到目标变量,全局作用域酒会创建一个具有该名称的变量;当执行RHS查询时,如果直到在全局作用域也找不到目标变量的话,就会抛出ReferenceError异常。如果RHS查询找到一个变量,但是你尝试对这个变量的值进行不合理的操作,那么引擎会抛出一个TypeError异常。ReferenceError同作用域判别失败相关,而TypeError则代表作用域判别成功了,但是对结果的操作是非法的。

函数作用域和块作用域

函数作用域
  • 函数作用域是指属于这个函数的全部变量都可以在整个函数的范围内使用及复用。
  • 如果function是声明中的第一个词,那么就是一个函数声明,否则就是一个函数表达式。

提升

  • 函数会首先被提升,然后才是变量。
  • 函数声明会被提升,但是函数表达式却不会被提升。如果在函数表达式所在的代码块前调用该函数,会抛出TypeError异常。如:
foo();
var foo=function bar(){
};
  • 重复的var声明会被忽略掉,但出现在后面的函数声明可以覆盖前面的。

闭包

  • 当函数可以记住并访问所在的词法作用域时,就产生了闭包。
  • 模块模式需要具备两个必要条件:
    1.必须有外部的封闭函数,该函数必须至少被调用一次(每次调用都会创建一个新的模块实例)。
    2.封闭函数必须返回至少一个内部函数,这样内部函数才能在私有作用域中形成闭包,并且可以访问或或者修改私有的状态。

关于this

  • this并不指向函数本身。
  • this不指向函数的作用域。(作用域“对象”无法通过JavaScript代码访问,它存在于Javascript引擎内部)。
  • this的值取决于函数的调用方式。
  • 不存在所谓的“构造函数”,只有对函数的构造调用。
  • this的绑定规则;
    1.默认绑定。独立函数调用,不带任何修饰的函数引用进行调用,默认绑定到全局对象,如果使用严格模式,this会绑定到undefined。
    2.隐式绑定。调用位置有上下文,即该函数被某个对象拥有或者包含,this绑定为该对象。
    3.显式绑定。’用过call()和apply()方法直接指定this的值。
    4.new绑定。只用new来调用函数,this绑定为该函数返回的对象。
  • this绑定的优先级。显式绑定优先级比隐式高,new绑定最高。
  • 当null或者undefined作为this的绑定对象传入call、apply或者bind,这些值会被忽略,实际应用的是默认绑定规则。

对象

类型
  • typeof null时会返回字符串“object”。原理是这样的,不同的对象在底层都表示为二进制,在JavaScript中二进制前三位都为0的话会被判为object类型,null的二进制全是0,自然前三位也是0,所以执行typeof时会返回“object”。
内置对象
  • null和undefined没有对应的构造形式,只有文字形式。相反,Date只有构造,没有文字形式。
属性描述符
  • 可以通过Object.defineProperty()来添加一个新属性。如:
var myObject={};
Object.defineProperty(myObject,"a",{
      value:2,
      writable:true,
      configurable:true,
      enumerable:true
});
不变性
  1. 对象常量 结合writable:false和configurable:fasle就可以创建一个真正的常量属性。
  2. 禁止扩展 如果想禁止一个对象添加新属性并且保留已有属性,可以使用Object.preventExtensions();
  3. 密封 Object.seal()会创建一个“密封”的对象,这个方法实际上会在一个现有对象上调用Object.preventExtensions()并把所有现有属性标记为configurable:false。
  4. 冻结 Object.freeze()会创建一个冻结对象,这个方法实际上会在一个现有对象上调用Object.seal()并把所有“数据访问”属性标记为writable:false,这样就无法修改它们的值了。
Getter和Setter
  • getter和setter是隐藏函数,作用在属性上。在ES5中可以用它们部分改写默认操作。
  • 当你给一个属性定义getter、setter或者两个都有时,这个属性会被定义为“访问描述符”,JavaScript会忽略它们的value和writable特性,取而代之的是关心set和get特性。
存在性
  • in操作符会检查属性是否在对象及器原型链中。相比之下,hasOwnProperty()智慧检查是否在当前对象中,不会检查原型链。

原型

  • for..in遍历对象时原理和[[Prototype]]类似,任何可以通过原型链访问到并且是可枚举的属性都会被枚举。使用in操作符检查属性在对象中是否存在时,同样会检查对象的整条原型链(无论属性是否可枚举)。
  • 所有普通的[[Prototype]]链最终都会指向内置的Object.prototype对象。
  • 当运行以下语句时:
    myObject.foo="bar";
    
    如果foo存在与原型链上层时,会出现以下三种情况(第二第三中情况只会发生在使用=操作符来赋值时):
    1.如果在[[Prototype]]链上层的foo没有被标记为只读,那就会直接在myObject上添加foo属性,它是屏蔽属性。
    2.如果在[[Prototype]]链上层的foo被标记为只读,那么无法修改或者在myObject上创建屏蔽属性。
    3.如果[[Prototype]]链上层的foo是一个setter,那么就会调用这个setter。foo不会被添加到myObject,也不会重新定义foo这个setter。
  • JavaScript并不会复制对象属性。相反,JavaScript会在两个对象之间创建一个关联,这样一个对象就可以通过委托访问另一个对象的属性和函数,所以JavaScript中并没有继承,也没有类。
  • 在JavaScript中对于“构造函数”最准确的解释是,所有带new的函数调用。
  • 举例来说,Foo.prototype的.constructor属性只是Foo函数在声明时的默认属性,如果用一个新对象替换了函数默认的。prototype对象引用,那么新对象并不会自动获得.constructor属性。
  • 如下面的代码
    function Foo(){}
    Foo.prototype={};
    var a1=new Foo();
    a1.constructor===Foo;//false
    a1.constructor===Object;//true
    
    a1并没有.constructor属性,所以它会委托[[Prototype]]链上的Foo.prototype。但是这个对象也没有.constructor属性(不过默认的Foo.prototype对象有这个属性),所以它会继续委托,这次会委托给委托链顶端的Object.prototype。这个对象有.constructor属性,指向内置的Object()函数。
  • 把一个对象关联到另一对象的安全的方式如下:
    //ES6以前的方式
    Bar.prototype=Object.create(Foo.protopyte) ;
    //ES6的方式
    Object.setPrototypeOf(Bar.rototype,Foo.prototype);
    
  • a instanceof Foo;instanceOf操作符的左操作数是一个普通对象,右操作数是一个函数。instanceOf回答的问题是:在a的整条[[Prototype]]链中是否有Foo.prototype指向的对象?这个方法只能处理对象和函数之间的关系。
  • .proto实际上并不存在于你正在使用的对象中,它和其他的常用函数(.toString(),.isPrototype(),等等)一样,存在与内置的Object.prototype中。此外,.proto看起来很像一个属性,但实际上它更像一个getter/setter
  • [[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();

相比面向对象风格来说,这段代码简洁了许多,我们是把对象关联起来,并不需要那些既复杂又令人困惑的模仿类的行为。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,497评论 18 139
  • 官方中文版原文链接 感谢社区中各位的大力支持,译者再次奉上一点点福利:阿里云产品券,享受所有官网优惠,并抽取幸运大...
    HetfieldJoe阅读 2,980评论 4 14
  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,093评论 0 13
  • 第十章天亮——希望你远走 上一章 表面上卞之和顾城进展顺利,有时卞之也这样认为。但顾城还是发现这几天卞之的心不在焉...
    一人的独角戏阅读 231评论 0 0
  • template 模块 1. <template> 标签上不要写多余的属性(默认就是以 html 来解析) 2. ...
    水流云间阅读 4,327评论 0 2