5_js对象、包装类、原型、原型链、call/apply

构造函数内部原理
  1. 在函数体最前面隐式的加上this = {}
  2. 执行 thisxxx=xxx;
  3. 隐式的返回this

构造函数只要在函数前面加个new

    function Student (name, age, sex) {
      //第一步:隐式生成 var this = {};
      //第二步:将this中赋值zhangsan、18、male
      this.name = name;
      this.age = age;
      this.sex = sex;
      this.grade = 2019;
      //第三步:将this赋值好的东西返回
    }
    var student = new Student('zhangsan', 18, 'male');
    console.log(student);

在这里插入图片描述
如果说你用了new,并且new的这个function中有return语句,那么它会自动把这个return语句忽略,并且return返回隐式生成的this变量

包装类
  • new String();
  • new Boolean();
  • new Number();
function Person(name, height) {
      // var this = {};
      this.name = name;
      this.height = height;
      return 123;// 但凡用的是new,就不可能返回原始值,必定返回隐式生成的this变量
    }
    var person = new Person('xiaowang', 180);// 控制台发现还是原样输出
    var person1 = new Person('xiaozhang', 175);
    // 包装类
    var num = 4;
    num.len = 3;
    // new Number(4).len = 3;---->delete  系统直接删除
    //
    // new Number(4).len 所以第二次查找这个len的时候就是undefined
    console.log(num.len);
    var str = "abc";
    str += 1; // str = "abc" + 1 = "abc1"
    var test = typeof (str); // test = "string"
    if(test.length == 6) {
      test.sign = "stypeof的返回结果可能为String"; // new String(test).sign = 'xxx'; --- delete
    }
    // new String(test).sign --> undefined
    console.log(test.sign);
    function Person (name, age, sex) {
      var a = 0;
      this.name = name;
      this.age = age;
      this.sex = sex;
      function sss () {
        a ++;
        document.write(a);
      }
      this.say = sss;
    }
    // 闭包
    var oPerson = new Person();// 生成执行上下文
    oPerson.say();// 1
    oPerson.say();// 2
    var oPerson1 = new Person();// 生成另一个执行上下文
    oPerson1.say();// 1

求字符串长度

    var str = "asd加油";
    function bytesLength (str) {
      // var count = str.length;
      // for(var i = 0; i < str.length; i++) {
      //   if(str.charCodeAt(i) > 255) {
      //     count++;
      //   }
      // }
      var count = 0;
      for (var i = 0; i < str.length; i++) {
        if(str.charCodeAt(i) > 255) {
          count += 2;
        } else {
          count++;
        }
      }
      return count;
    }
    console.log(bytesLength(str));
原型
  1. 定义:原型是 function对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法。原型也是对象。
  2. 利用原型特点和概念,可以提取共有属性。
  3. 对象如何查看原型一>隐式属性__proto__
  4. 对象如何查看对象的构造函数一> constructor
    // Person.prototype -- 原型
    // Person.prototype = {} 是祖先
    Person.prototype.LastName = "xx";
    Person.prototype.say = function () {
      console.log('say')
    }
    function Person (name, age, sex) {
      this.name = name;
      this.age = age;
      this.sex = sex;
    }
    var person = new Person('xiaoming', 35, 'male');
    // 打印出后,在person下的__proto__下有LastName
    console.log(person);// {name: "xiaoming", age: 35, sex: "male"} person.LastName:xx
    var person1 = new Person();
    console.log(person1);// {name: undefined, age: undefined, sex: undefined} person.LastName:xx

在这里插入图片描述

    Person.prototype.name = 'sunny';
    function Person() {
      // var this = {
      //    __proto__ : Person.prototype
      // };
    }
    Person.prototype.name = 'cherry';
    var person = new Person();// person.name : 'cherry'
    Person.prototype.name = 'sunny';
    function Person() {
      // var this = {
      //    __proto__ : Person.prototype
      // };
    }
    Person.prototype.name = {
    
    };
    var person = new Person();// person.name : 'cherry'
    Person.prototype.name = 'sunny';
    function Person() {
    }
    Person.prototype = {
      name : 'cherry'
    };// 执行顺序,先改了prototype,所以person中的name属性为'cherry'
    var person = new Person();
    // Person.prototype = {
    //   name : 'cherry'
    // };// 把上面的一样的代码注释掉,把它移到下面来,就不一样了,首先,先执行new Person(),这样person指向了‘sunny’,后面不管怎么变,引用值还是‘sunny’
原型链
  • 如何构成原型链?

    因为每个对象和原型都有原型,对象的原型指向原型对象,
    而父的原型又指向父的父,这种原型层层连接起来的就构成了原型链。

  • 原型链上属性的增删改查
  • 绝大多数对象的最终都会继承自Object. prototype

为什么说是绝大多数的对象呢,因为有个特例,create(null)
在这里插入图片描述

  • Object create(原型)

方法的重写:

Person.prototype = {
	  // 重写了toString的方法
      toString : function () {
        return 'xxx';
      }
    }
    function Person () {

    }
    var person = new Person();

JavaScript自带的方法也有重写的:
Object.prototype.toString
Number.prototype.toString
Array.prototype.toString
Boolean.prototype.toString
String.prototype.toString

Math.ceil() —>向上取整
Math.ceil(123.234)
124

Math.floor() —>向下取整
Math.floor(123.999999999)
123

Math.random() —>(0,1)之间的随机数
随机数两位小数:

    for(var i = 0; i < 10; i++) {
      var num = (Math.random() * 100).toFixed(2);// 因为JavaScript小数精度不太准,所以先乘一百,再取两位
      console.log(num)
    }

javaScript可正常计算的范围 小数点前十六位、后十六位

call/apply

作用,改变this指向
区别,后面传的参数形式不同。

call:

    function Person (name, age, sex) {
      this.name = name;
      this.age = age;
      this.sex = sex;
    }
    function Student (name, age, sex, tel, grade) {
      Person.call(this, name, age, sex);// 利用Person的代码,实现自己的封装
      //Person.apply(this, [name, age, sex]);
      this.tel = tel;
      this.grade = grade;
    }
    var student = new Student('sunny', 123, 'male', 139, 2019);

call 需要把实参按照形参的个数传进去
apply 需要传一个arguments

发布了56 篇原创文章 · 获赞 20 · 访问量 7399

猜你喜欢

转载自blog.csdn.net/qq_36826618/article/details/102595124