美文网首页
JavaScript学习——对象

JavaScript学习——对象

作者: ting723 | 来源:发表于2015-08-04 22:33 被阅读130次
    1. 本文是在学习廖雪峰先生的JavaScrip教程 后的归纳

    一、标准对象

    1. typeof
      • JavaScript的世界,一切都是对象
      • typeof操作符获取对象的类型,总是返回一个字符串
      typeof 123; // 'number'
      typeof NaN; // 'number'
      typeof 'str'; // 'string'
      typeof true; // 'boolean'
      typeof undefined; // 'undefined'
      typeof Math.abs; // 'function'
      typeof null; // 'object'
      typeof []; // 'object'
      typeof {}; // 'object'
      
      • numberstringbooleanfunctionundefined有别于其他类型
      • nullArray{}的类型是object,故typeof无法区分三者
    2. 包装对象
      • numberboolean、和string都有包装类型,使用new创建
      var n = new Number(123); // 123,生成了新的包装类型
      var b = new Boolean(true); // true,生成了新的包装类型
      var s = new String('str'); // 'str',生成了新的包装类型
      
      • 包装对象虽和原来的值一样,但类型已经发生变化,都变成object
      • 尽量不要使用包装类型,尤其是string类型
      • NubmerBooleanString没写new时,可以被当成普通函数,把任何类型的数据转换为numberbooleanstring类型(不是包装类型)
      var n = Number('123'); // 123,相当于parseInt()或parseFloat()
      typeof n; // 'number'
      
      var b = Boolean('true'); // true
      typeof b; // 'boolean'
      
      var b2 = Boolean('false'); // true! 'false'字符串转换结果为true!因为它是非空字符串!
      var b3 = Boolean(''); // false
      
      var s = String(123.45); // '123.45'
      typeof s; // 'string'
      
    3. 总结
      • 不要使用new Number()、new Boolean()、new String()创建包装对象;
      • parseInt()parseFloat()来转换任意类型到number
      • String()来转换任意类型到string,或者直接调用某个对象的toString()方法;
      • 通常不必把任意类型转换为boolean再判断,因为可以直接写if (myVar) {...}
      • typeof操作符可以判断出number、boolean、string、function和undefined
      • 判断Array要使用Array.isArray(arr)
      • 判断null请使用myVar === null
      • 判断某个全局变量是否存在用typeof window.myVar === 'undefined'
      • 函数内部判断某个变量是否存在用typeof myVar === 'undefined'
      • nullundefined 没有toString()方法
      • 特殊情况:number使用toString()方法
      123..toString();//两个点
      (123).toString();
      

    二、Date

    1. Date表示日期和时间
      • 获取系统时间如下:
      var now = new Date();
      now; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST)
      now.getFullYear(); // 2015, 年份
      now.getMonth(); // 5, 月份,注意月份范围是0~11,5表示六月
      now.getDate(); // 24, 表示24号
      now.getDay(); // 3, 表示星期三
      now.getHours(); // 19, 24小时制
      now.getMinutes(); // 49, 分钟
      now.getSeconds(); // 22, 秒
      now.getMilliseconds(); // 875, 毫秒数
      now.getTime(); // 1435146562875, 以number形式表示的时间戳
      
      • 创建一个指定日期和时间的Date对象,可以用:
      var d = new Date(2015, 5, 19, 20, 15, 30, 123);
      d; // Fri Jun 19 2015 20:15:30 GMT+0800 (CST)
      
      • JavaScript的月份范围用整数表示是0-11
      • 创建一个指定日期和时间的方法是解析一个符合ISO 8601格式的字符串
      • Data.parse('2015-06-24T19:49:22.875+08:00'); 返回一个时间戳;该时间戳很容易转换成Date
    2. 时区
      • Date对象表示的时间总是按浏览器所在时区显示的,不过,我们既可以显示本地时间,也可以显示调整后的UTC时间
      var d = new Date(1435146562875);
      d.toLocaleString(); // '2015/6/24 下午7:49:22',本地时间(北京时区+8:00),显示的字符串与操作系统设定的格式有关
      d.toUTCString(); // 'Wed, 24 Jun 2015 11:49:22 GMT',UTC时间,与本地时间相差8小时
      
      • 时间戳: 是一个自增的整数,它表示从1970年1月1日零时整的GMT时区开始的那一刻,到现在的毫秒数。

    三、RegExp

    1. 基本
      • \d可以匹配一个数字,\w可以匹配一个字母或数字
      • .可以匹配任意字符,*表示任意个字符,用+表示至少一个字符,?表示0个或1个字符,用{n}表示n个字符,用`{n,m}表示n-m个字符
      • \s可以匹配一个字符(也包括Tab等字符)
    2. 进阶
      • []表示范围,A|B可以匹配A或B
      • ^ 表示行的开头,^\d表示必须以数字开头
      • & 表示行的结束
    3. JavaScript中使用正则表达式
      • 写法一: /正则表达式/
      • 写法二: new RegExp('正则表达式)`创建一个RegExp对象
      • 示例:
        var re = /^\d{3}\=\d{3,8}$/;
        re.test('010-12345');//true
        
      • RegExp对象test()方法用于测试给定的字符串是否符合规定
      • 切分字符串:用正则表达式来把不规范的输入转化成正确的数组
      • 分组:提取子串的功能,通过()表示的就是要提取的分组(Group)
        var re = /^(\d{3})-(\d{3,8})$/;
        re.exec('010-12345'); // ['010-12345', '010', '12345']
        re.exec('010 12345'); // null
        
        在正则表示式中定义了组,就可以在RegExp对象上用exec()方法提取出子串来
        exec()方法在匹配成功后,会返回一个Array,第一元素始终是原始字符串本身,后面的字符串表示匹配成功的子串
        exec()方法在匹配失败后,返回null
      • 正则表达式默认的是贪婪匹配,也就是匹配尽可能多的字符
      • \d+加个?就可以采用贪婪匹配
    4. 全局搜索
      • g表示全局匹配
      • var r1 = /test/g; 等价于 var r2=new RegExp('test','g');
      • 全局匹配可以多次执行exec()方法来搜索一个匹配的字符串,当指定g标志后,每次运行exec(),正则表达式本身会更新lastIndex属性,表示上次匹配到的最后索引
      var s = 'JavaScript, VBScript, JScript and ECMAScript';
      var re=/[a-zA-Z]+Script/g;
      
      // 使用全局匹配:
      re.exec(s); // ['JavaScript']
      re.lastIndex; // 10
      
      re.exec(s); // ['VBScript']
      re.lastIndex; // 20
      
      re.exec(s); // ['JScript']
      re.lastIndex; // 29
      
      re.exec(s); // ['ECMAScript']
      re.lastIndex; // 44
      
      re.exec(s); // null,直到结束仍没有匹配到
      
      • 全局匹配类似搜索,因此,不能使用/^...$/,那样只会最多匹配一次
      • 正则表达式还可以指定i标志,表示忽略大小写,m标志,表示执行多行匹配

    四、JSON

    1. 定义
      • JSON是JavaScript Object Notation的缩写,是一种数据交换格式
      • 由道格拉斯·克罗克福特(Douglas Crockford)发明
      • JSON实际上是JavaScript的一个子集
      • JSON数据类型和JavaScript基本一样: number,boolean,string,null,array,object以及前面的任意组合
      • JSON定死了字符集为UTF-8,对多语言没有问题
      • 为了统一解析,JSON的字符串规定必须用"",Object的键也必须用双引号""
      • 把任何JavaScript对象变成JSON,就是把这个对象序列化成一个JSON格式的字符串
      • 收到一个JSON格式的字符串,只需要把它反序列化成一个JavaScript对象
    2. 序列化
      • 示例:
      var xiaoming = {
          name: '小明',
          age: 14,
          gender: true,
          height: 1.65,
          grade: null,
          'middle-school': '\"W3C\" Middle School',
          skills: ['JavaScript', 'Java', 'Python', 'Lisp']
      };
      
      JSON.stringify(xiaoming); // '{"name":"小明","age":14,"gender":true,"height":1.65,"grade":null,"middle-school":"\"W3C\" Middle School","skills":["JavaScript","Java","Python","Lisp"]}'
      
      • 输出比较规范: JSON.stringify(xiaoming, null, ' ');
      • JSON.stringify(xiaoming,['name','skill'],' ');
        第二个参数用来筛选对象的键值,只输出指定的属性,则Array
      • JSON.stringify(xiaoming, convert, ' ');还可以传入一个函数(function convert(key,value){})
      • 还可以为对象定义一toJSON()方法
      var xiaoming = {
          name: '小明',
          age: 14,
          gender: true,
          height: 1.65,
          grade: null,
          'middle-school': '\"W3C\" Middle School',
          skills: ['JavaScript', 'Java', 'Python', 'Lisp'],
          toJSON: function () {
              return { // 只输出name和age,并且改变了key:
                  'Name': this.name,
                  'Age': this.age
              };
          }
      };
      
      JSON.stringify(xiaoming); // '{"Name":"小明","Age":14}'
      
    3. 反序列化
      • 拿到一JSON格式的字符串,我们直接用JSON.parse()把它变成一个JavaScript对象
      • 示例:
      JSON.parse('[1,2,3,true]'); // [1, 2, 3, true]
      JSON.parse('{"name":"小明","age":14}'); // Object {name: '小明', age: 14}
      JSON.parse('true'); // true
      JSON.parse('123.45'); // 123.45
      
      • JSON.parse()可以接收一个函数,用来转换解析出来的属性
      • 示例:
      JSON.parse('{"name":"小明","age":14}', function (key, value) {
           // 把number * 2:
           if (key === 'name') {
               return value + '同学';
           }
           return value;
      });// Object {name: '小明同学', age: 14}
      

    五、面向对象编程

    1. 面向对象
      • 类和实例是大多数面向对象编程的基本概念
      • JavaScript中,JavaScript不区分类和实例的概念,而是通过原型(prototype)来实现面向对象编程
      • 示例:
      var Student = {
          name: 'Robot',
          height: 1.2,
          run: function () {
              console.log(this.name + ' is running...');
          }
      };
      
      var xiaoming = {
          name: '小明'
      };
      
      xiaoming.__proto__ = Student;
      
      • JavaScript的原型链和Java的Class的区别就是在于,JavaScript没有"Class"概念,所有对象都是实例,所谓继承关系不过是把一个对象的原型指向另一个对象而已
      • 编写JavaScript代码时,不要直接用obj.__proto__去改变一个对象的原型,可以使用Object.create()方法可以传入一个原型对象,并创建一个基于该原型的新对象,但新对象什么属性都没有
      • 示例:
      function createStudent(name) {
          // 基于Student原型创建一个新对象:
          var s = Object.create(Student);
          // 初始化新对象:
          s.name = name;
          return s;
      }
      

    六、创建对象

    1. 原型链
      • JavaScript对每个创建的对象都会设置一个原型,指向它的原型对象
      • 当使用obj.xxx访问一个对象的属性时,JavaScript引擎先在当前对象上查找该属性,如果没有找到,就到其原型对象上找,如果还没找到,就到Object.prototype对象,最后还没找到,就只能返回undefined
        示例:
      var arr=[1,2,3];
      原型链是:
          arr---->Array.prototype-->Object.prototype--->null
      其中`Array.prototype`定义了`indexOf()`、`shift()`等方法,
       因此可以在所有`Array`对象上直接调用执行方法
      
      function foo(){
          return 0;
      }
      foo--->Function.prototype--->Object.prototype--->null
      其中Function.prototype定义了apply()方法
      
      • 如果原型链很长,那么访问一个对象的属性会因为耗费更多时间查找而变得更慢,因此,原型链不宜太长
    2. 构造函数
      • 除了{...}直接创建对象外,还可以通过构造函数的方法来创建对象
      • 示例:
      function Student(name) {
          this.name = name;
          this.hello = function () {
              alert('Hello, ' + this.name + '!');
          }
      }   
      
      var xiaoming=new Student('xiaoming');
      原型链如下:
      xiaoming---->Student.prototype--->Object.prototype--->null
      
      • 在JavaScript中,可以用关键字new来调用这个函数,并返回一个对象
      • 不写new,是个普通函数,加上new就变成一个构造函数,它绑定this指向新创建的对象,并默认返回this,即不需要在最后加return this
      • new Student()创建的对象还从原型上获得了一constructor属性,其指向Student本身
      xiaoming.constructor === Student.prototype.constructor; // true
      Student.prototype.constructor === Student; // true
      Object.getPrototypeOf(xiaoming) === Student.prototype; // true
      xiaoming instanceof Student; // true
      
      • 让创建对象共享一个函数时,根据对象的属性查找原则,可以把函数移到对象共同的原型上
      • 为了区分普通函数和构造函数,按照约定,构造函数首字母大写,而普通函数首字母小写
      • 一个常用的编程模式:
      function Student(props) {
          this.name = props.name || '匿名'; // 默认值为'匿名'
          this.grade = props.grade || 1; // 默认值为1
      }
      Student.prototype.hello = function () {
          alert('Hello, ' + this.name + '!');
      };
      function createStudent(props) {
          return new Student(props || {})
      }
      var xiaoming = createStudent({
          name: '小明'
      });
      
      xiaoming.grade; // 1
      优点: 这个`createStudent()`函数有几个优点:
          a. 不需要new来调用
          b. 参数非常灵活,可以传参,也可以不传参
      

    七、原型继承

    1. 继承
      • Java等传统的基于Class语言,本质上是扩展一个已有的Class,并生成新的Subclass,由于这类语言严格区分类和实例,继承实际上是类型的扩展
      • JavaScript 采用的原型继承,无法直接扩展一个Class
      • JavaScript的原型继承实现方式就是:
        • 定义新的构造函数,并在内部用call()调用希望"继承"的构造函数,并绑定this
        • 借助中间函数F实现原型链继承,最好通过封装的extendes函数完成
        • 继续在新的构造函数的原型上定义新方法

    相关文章

      网友评论

          本文标题:JavaScript学习——对象

          本文链接:https://www.haomeiwen.com/subject/npymqttx.html