js权威指南笔记

字符串不是对象,为什么具备属性?

只要引用了字符串的属性,JavaScript 就会将字符串通过new String(str)的 方式转换成对象,这个对象继承了字符串的方法,并用来处理属性的引用,一旦引用结束,这个创建的对象就会销毁。

同字符串一样,数字和布尔值也具备各自的方法:通过Number()Boolean()构造函数创建一个临时对象。null和undefined 没有包装

var s = 'test';  
s.len = 2;
console.log(s.len); // undefined

当运行的时候,s.len 是undefined,当给s.len 赋值的时候,内部会new String(s); 赋值完毕后会销毁,所以s.len,没有被保留下来


重复的声明和遗漏的声明

使用var语句重复声明变量是合法且无害的,如果重复声明带有初始化器,那么就和赋值语句没什么两样。
如果读取一个没有声明的变量的值,js 会报错,在严格模式中,给没声明的变量赋值也会报错。
非严格模式下,给一个为声明的变量赋值,js实际上会给全局对象创建一个同名属性,并且它看起来就像一个全局属性(但不完全一样);


作用域

作用域是变量在代码中定义的区域,全局变量拥有全局作用域,在JavaScript代码中的任何地方都是有定义的。然而在函数内部的变量,它们是局部变量,作用域是局部性的。函数参数也是局部变量,它们只在函数体内有定义。

在函数体内,局部变量的优先级高于同名的全局变量。如果函数体内声明的局部变量或者函数参数变量和全局变量重名,那么全局变量会被局部变量所掩盖。

var scope = "global";
function scope_demo(){
    var scope = "function";
    return scope;
}
console.log(scope_demo()); //function 

在函数体内声明scope的时候 ,声明一个局部变量,在函数体内使用scope 会优先调用到局部变量。


变量提升和函数作用域

在一些类似C语言的编程语言中,花括号内的每一段代码都具有各自的作用域,而且变量在声明它们的代码段之外是不可见的,我们成为 块级作用域(block scope),在javascript 中没有块级作用域,javascript取而代码的使用了函数作用域(function scope) ,变量在它们的函数体内和嵌套函数体内都是有定义的。

function test(o){
    console.log(o,j,i); //o 是实参,j是undefined,i是0
    var i = 0;
    if(typeof o == 'object'){
        var j = 0;
        for(var k = 0;k<10;k++){
            console.log(k);
        }
    }
}
test(1);
//输出 1,undefined,undefined;  1是o的实参,j 变量提升,但是值是undefined,i也一样

JavaScript的函数作用域是指在函数内声明的所有变量,在函数体内始终是可见的,有意思的是,在变量声明之前已经可以使用,JavaScript 的这个特性被称为声明提前(变量提升):JavaScript 函数里声明的所有变量(但不涉及赋值)都被提前 函数的顶部


作用域链

JavaScript 是基于词法作用域的语言。全局变量在程序中使用都是有定义的。局部变量在声明它的函数体内以及所嵌套的函数内使用时有定义的。

如果将一个局部变量看做时自定义实现的对象的属性的。那么可以换个角度来解读变量作用域。每一段javascript代码(全局或函数)都有一个与之关联的作用域链(scope chain)。这个作用域链是一个对象或者链表,这组对象定义个这段代码"作用域中"的变量。**当javascript需要查找变量x的值得时候(这个过程叫做"变量解析"),它会从链中的第一个对象开始查找,如果这个对象有名为x的属性,则会直接使用这个属性的值,如果第一个对象不存在x属性,javascript会继续查找链上的下一个对象,直到找到为查找到最后,没有找到,javascript会认为作用域链上不存在x,并抛出一个引用异常。


对象

对象是javascript的基本数据类型。对象是一种复合值,它将很多值聚合在一起。可通过名字访问这些值。对象也可以看做属性的无序集合,每个属性都是一个键值对,属性是字符串。

对象不仅仅是保持字符串到值得映射,除了可以保持自有的属性,javascript 对象还可以从一个称为原型的对象集成属性。这种"原型式继承"式javascript的核心特征。

javascript 对象是动态的,–可以新增也可以删除-- 但它们通常用来模拟静态语言中的 “结构体”,有事和会用作字符串的集合

对象最常见的用法是 创建、设置、查找、删除、检测和枚举它的属性。除了名字和值之外,每一个属性还有一些与之相关的值,称为"属性特性":

  • 可写(writable attribute),表明是否可以设置该属性的值
  • 可枚举(enumerable attribute),表明是否可以通过for/in循环返回该属性。
  • 可配置(configurable attrbute) ,表明是否可以删除或修改该属性。

在Ecmascript5之前,通过代码给对象创建的所有属性都是可写的、可枚举的和可配置的。

除了包含属性之外,每个对象还拥有三个相关的对象特性:

  • 对象的原型(prototype)指向另一个对象,本对象的属性继承自它的原型对象。
  • 对象的类(class)是一个标识对象类型的字符串。
  • 对象的拓展标记(extensible flag)知名了是否可以向该对象添加新属性。

三类对象、两类属性:

  • 内置对象:数组、函数、日期、正则都是内置对象;
  • 宿主对象:由javascript 解释器所嵌入的宿主环境(比如web浏览器)定义的。
  • 自定义对象:由javascript 代码创建的对象。
  • 自有属性:直接在对象中定义的属性。
  • 继承属性:对象 原型链上定义的属性。

对象的创建:

  • 对象直接量

    创建对象最简单的方式就是在javascript代码中使用对象直接量。

        var hello = {
            a:1,
            x:2
        }
    
  • 通过new 创建对象

    new 运算符创建并初始化一个新对象,关键字new后跟随一个函数调用。这里的函数称作构造函数,构造函数泳衣初始化一个新创建的对象。javascript语言中核心的原始类型都包含内置构造函数。例如:

    var o = new Object(); //创建一个新对象,和{}一样。
    var a = new Array(); //创建空数组,和[]一样。
    var d = new Date();  //创建一个当前时间的对象
    var r = new RegEx('js');  //创建一个正则对象。
    
  • 理解对象

    • 对象属性 (IE8以下不可使用,不建议在IE8使用)

      • Configurable 是否可以用delete 删除
      • Enumerable 是否可以用for-in循环
      • Writable 是否可以修改,默认true,如果设置为false,在严格模式下修改会报错,非严格模式修改无效
      • Value
      var Person = {};
      Object.defineProperty(Person,"name",{
          writable:false, //现在person.name不能被修改
          value:"person_name" //默认值
      });
      
    • 访问器属性

      访问器属性不包含数据值,他们包含一堆getter、setter方法(不是必须的),当读取属性时,会调用getter方法,赋值属性会调用setter方法

       var Book = {
          name: 'JavaScript高级程序设计',
          size2: 1
      };
      
      Object.defineProperty(Book, "sizi", {
          get: function () {
              return this.name.length;
          },
          set: function (newValue) {
              //newValue 要赋的值
              this.size2 = newValue;
          }
      });
      

      支持ES5的这个方法只有IE9+,在这个方法之前,有两个非标准的方法__defineGetter____defineSetter__方法

  • 定义多个属性

    • Object.defineProperties();
        var book = {};
        Object.defineProperties(book, {
            _year: {
                value: 2004
            },
            edition: {
                value: 1
            },
            year: {
                get: function(){
                    return this._year;
                },
                set: function(newValue){
                    if (newValue > 2004) {
                    this._year = newValue;
                    this.edition += newValue - 2004;
                    }
                }
            }
        });
        
    
  • 原型

    原型:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值