今日学习JS进阶之创建对象(一)

89 阅读5分钟

1.创建工厂函数

题目要求

创建一个工厂函数 createPerson, 需要完成以下要求:

  • 工厂函数依次接受参数 nameagesex

  • 调用工厂函数将返回一个生成的对象

    • 返回的对象带有 name、 age、 sex 的属性,值来自传入的参数
    • 返回的对象带有 sayHello 的方法,调用 sayHello 方法将在控制台上(console.log)输出对象的 name 属性。

如下所示:

var person1 = createPerson('jero', 26, 'male');
console.log(typeof person1 === 'object'); // true
console.log(person1.name);  // jero
console.log(person1.age); // 26
console.log(person1.sex); // male
person1.sayHello(); // jero
function createPerson(name, age, sex) {
    return {
        name: name,
        age: age,
        sex: sex,
        sayHello: function() {
            console.log(this.name);
        }
    };
}
var person1 = createPerson('guo','19','female');
console.log(typeof person1 === 'object');
console.log(person1.name);
console.log(person1.age);
console.log(person1.sex);
person1.sayHello();

  • 缺点:无法证明person1是一个creatPerson的示例对象 所以需要用构造函数改进 那么我们就再复习一下函数

2.根据输入参数拼接字符串

题目要求

创建一个函数 announce, 需要完成以下要求:

  1. 函数可接受不定数目的参数
  2. 拼接所有参数成一句完整的字符串
  3. 最终返回拼接好的字符串

如下所示:

var resultStr = announce('Tom', 'Jack', 'Mike');
console.log(resultStr);  // 获得本次大会第一名的共有3人,分别是Tom、Jack、Mike。

如上面代码中,传入参数 TomJackMike,便输出下面的话。

获得本次大会第一名的共有3人,分别是Tom、Jack、Mike

注: 其中黑色的部分为固定内容的,红色的文字部分为根据传入参数的内容进行设置。

使用循环语句拼接

使用循环的方式,相信大家都很熟悉。

function announce() {
    var len = arguments.length;
    var resultStr = '获得本次大会第一名的共有'+ len + '人,分别是';
    for(var i = 0; i < len; i++) {
          if(i != len-1) {
            resultStr += arguments[i] + '、';
          }
          else {
            resultStr += arguments[i] + '。'
          }
    }
    return resultStr;
}
var resultStr = announce('Tom','Jack', 'Mike');
console.log(resultStr);

借用数组的 join 方法

function announce() {
    var len = arguments.length;
    var resultStr = '获得本次大会第一名的共有' + len + '人,分别是';
    resultStr += Array.prototype.join.call(arguments, ' 、');
    resultStr += '。';
    return resultStr;
}
var resultStr = announce('Tom','Jack','Mike');
console.log(resultStr);

方法详情点此

3.this问题(判断下面程序输出结果)

    var price = 10;
    var apple = {
        price: 8,
        getPrice: function() {
            return this.price;
        }
    };
    var getPrice = function() {
        return price;
    }
    var result1 = getPrice(); //10 全局函数返回全局变量
    console.log(apple.getPrice); //这个大家可以先输出一下 输出的仅仅是apple里的方法
    var getPrice = apple.getPrice; //所以这相当于把getPrice重新定义 变成return this.price;
    var result2 = getPrice();//10 重新定义之后又调用重新定义后的getPrice还是全局函数 所以this指向全局变量10
    var result3 = apple.getPrice();//8 毋庸置疑是apple调用的this指向apple 所以是8
    console.log(result1,result2,result3);
 var price = 1;
    var apple = {
        price: 8,
        getPrice: function() {
            return this.price;
        }
    };
    var orange = {
        price: 10,
        getPrice: function() {
            return this.price * 2;
        }
    }
    var result1 = orange.getPrice(); //20 毋庸置疑是orange的方法 this指向10 10*2=20
    var result2 = apple.getPrice.apply(orange); //10 apple的方法 但是this改变了指向 8变为10
    var result3 = orange.getPrice.call(this); //2 this指向改变 变为全局 直接由10*2 变成了 1*2
    console.log(orange.getPrice);
    orange.getPrice = orange.getPrice.bind(apple); //给orange的方法getPrice重新定义 改变this指向 指向apple的8
    console.log(orange.getPrice);
    var result4 = orange.getPrice();//16  2*8 = 16
    console.log(result1, result2, result3, result4);

  • 附加一道 函数常见的三个属性 name length prototy(原型后面会有重大作用)
    function demo(arg1,arg2) {
        console.log(demo.name);
        console.log(demo.length); //2 形参个数
        console.log(arguments.length);// 3 实参个数
     }
     demo('a','b','c');

4.啥是闭包

  • 定义:首先闭包是一个函数 一个什么样的函数呢? 一个能调用另一个函数作用域中变量的函数 直接上题

创建一个私有变量

如果我们需要隐藏一些不应该被直接修改的数据,我们需要使用到私有变量特权方法。那么什么是私有变量和特权方法呢?

什么是私有变量?

对于私有变量,我们需要理解下面的两句话:

  • 任何在函数中定义的变量,都可以认为是私有变量。因为不能在函数外部访问这些变量。
  • 私有变量包括函数参数,局部变量以及在函数内部定义的其他函数。

如下面的代码,在这个函数内部,有三个私有变量 paramprivateVariable、 privateFunction。在函数内部可以访问到这几个变量,但在函数外部则不能访问他们。

function MyObject(param) {
  var privateVariable = 20;
  function privateFunction(){
      return true;
  }
}
// 在函数外部无法直接访问到私有变量和方法

创建特权方法来访问私有变量

那么,我们如果需要访问私有变量时,可以怎么做呢?

我们可以在函数的内部创建一个闭包,那么闭包通过自己的作用域链也可以访问这些变量。而利用这一点,我们就可以创建用于访问私有变量的公有方法。

我们也把有权访问私有变量和私有函数的公有方法称为特权方法

如下面的代码,publicMethod 就是特权方法。在创建 MyObject 的实例后,除了使用特权方法 publicMethod 这一途径外,没有其他的办法可以直接访问来访问私有变量 privateVariable 以及私有函数 privateFunction

function MyObject(param) {
  var privateVariable = 20;
  function privateFunction(){
      return 10;
  }
  // 特权方法
  this.publicMethod = function(){
      privateVariable ++;
      return privateFunction();
  }
}

题目要求

完善工厂函数 createPerson, 需要完成以下要求:

  • 保存传入参数 name 到一个私有变量中
  • 函数返回一个对象,且对象带有一个特权方法 getName,用于返回对象的私有变量 name 的值

如下所示:

var person = createPerson('Jero');
console.log(person.name);  // undefined
console.log(person.getName()); // Jero
function createPerson(name) {
            var privateVariable = name;

            return {
                getName: function () {
                    return privateVariable;
                }
            }
        }
        var person = createPerson('jero');
        console.log(person.name);
        console.log(person.getName());