javaScript(小细节)你了解吗?instanceof、面向对象的设计模式...

前言

秉着学习、交流、思考、总结的态度,和你们分享这段时间经过阅读js高级程序设计,发现的一些小细节,小知识点,一块儿交流,一块儿进步!查漏补缺ing...javascript

操做符----instanceof

  • 在 JavaScript 中,咱们判断一个变量的类型经常会用 typeof 运算符,在使用 typeof 运算符时采用引用类型存储值会出现一个问题,不管引用的是什么类型的对象,它都返回 "object";
  • instanceof 与 typeof 方法不一样的是,instanceof 方法帮助开发者明确地确认对象为某特定类型。
var obj = new Object("some texrt");
console.log(obj instanceof Number);	//输出 false
console.log(obj instanceof String);	//输出 true
复制代码
  • 原理:instanceof是根据引用数据类型的prototype来判断真实的数据类型。

变量、做用域和内存问题

  • 复制变量值问题前端

    • var num = 2;
      var num1  = num;   // 此时 num1 = 2 复制了num
      var num1 = 3;    //此时num1 = 3,num依然为2
      复制代码
    • var obj1 = new Object()
      var obj2 = obj1;
      obj1.name = "MG";
      alert(obj2.name); //此时obj2.name = MG
      复制代码

    变量对象的指向: obj1建立了一个对象新实例,而后复制给了obj2。此时他们指向的都是堆内存中的同一个对象;当obj1添加name属性以后,obj2来访问这个属性,此时他们访问的都是存储在这个堆内存中的一个对象。java

  • 声明变量算法

    function add(num1,num2){
          var sum = num1+num2;
          return sum;
      }
      var result = add(10,20);
      alert(sum);	// sum is not defined---(var声明在了局部环境,全局没法访问到)
    复制代码
    function add(num1,num2){
            sum = num1 + num2;
            return sum
        }
        var result = add(10,20)
        alert(sum);	// 30
    复制代码

    var: var声明变量会自动被添加到最接近的环境中;在函数内部最接近的环境就是函数的局部环境;若是初始化变量时(代码块2所示),没有使用var关键字,因此sum属于全局环境,那么当add()执行完毕以后,sum也能够被访问到。设计模式

  • 垃圾收集机制函数

    • javascript内部机制具备自动垃圾收集机制。没必要关心内存分配和回收问题。
    • 标记清除是主流的垃圾收集算法。另一种是引用计数算法。

建立对象

  • 工厂模式学习

    • 这是一种广为人知的设计模式,说白了就是实现同一事情的相同代码,放到一个函数中,之后若是再想实现这个功能,就不须要从新编写这些代码了,只要执行当前的函数便可;
    • 弊端:这种模式没有解决对象识别的问题(即怎样知道一个对象的类型)用起来仍是不够灵活;
    function creatPerson(name,age,job){
         var o = new Object();    // 新建一个函数
         o.name = name;
         o.age = age;
         o.job = job;
         o.sayName = function (){
             alert (this.name);
         };   
         return o;
     }
     var person1 = creatPerson("mangguo",21,"fe");
     var person2 = creatPerson("MG",21,"前端");
    复制代码
  • 构造函数模式ui

    • 典型用法是:new操做符来建立一个新的对象;注意哦,构造函数模式函数名首字母要使用大写;
    • 弊端:这种构造函数的方式会致使不一样的做用域链和标识符被解析,可是建立新实例的机制仍然是相同的;
    function Person(name,age,job){
         var o = new Object();    // 新建一个函数
         o.name = name;
         o.age = age;
         o.job = job;
         o.sayName = function (){
             alert (this.name);
         }; 
     }
     var person1 = new creatPerson("mangguo",21,"fe");
     var person2 = new creatPerson("MG",21,"前端");
    复制代码

小伙伴们能够根据这些实例,本身总结一下上边的这两种模式还有什么不同的地方,进一步巩固哦!this

  • 原型模式spa

    • hasOwnProperty()方法,能够用来检测一个属性是存在于实例中,仍是存在于原型中;
    • 只有当实例真正重写原型里边的属性时, hasOwnProperty()才会返回true;
    • 使用in操做符时,只要经过对象可以访问到属性就会返回true;
    • 要注意区别 hasOwnProperty()和 hasPrototyeProperty();当对象属性重写以后,hasPrototyeProperty()会返回false;
    • 实例和原型之间的链接是一个指针prototype
    function Person(){}
       Person.prototype = {
            name :"MG",
            adress :"beijing",
            sayName :(()=>{ 
            console.log(this.name);
       	  }) 
        }
        var person1 = new Person();
        var person2 = new Person();
        console.log(person1.hasOwnProperty("name"));	// 输出 false
    	console.log("name" in person1);	// 输出 true
        person1.name = "mangguo"
        console.log(person1.hasOwnProperty("name"));	// 输出 true
    	console.log("name" in person1);	// 输出 true
    复制代码
  • 构造函数和原型混成的模式

    • 混成模式集两种模式之长,是目前使用最普遍,认同度最高的一种建立自定义类型的方法;
    • 这样会最大程度的节省内存,这样的实例就会不只有本身的实例属性,还会共享着原型上的属性和方法,真正的实现1+1>2;
    function Person(name,age,job){
         var o = new Object();    // 新建一个函数
         o.name = name;
         o.age = age;
         o.job = job;
         this.friends = ["Mar","Court"];
     }
     Person.prototype = { 
          constructor:Person, // 这里是声明全部实例的共享属性,constructor'
          sayName:function(){
              alert(this.name);
          }
      }
     var person1 = new creatPerson("mangguo",21,"fe");
     var person2 = new creatPerson("MG",21,"前端");
     person1.friends.push("Van");
     console.log(person1.friends);    // 输出 "Mar, Court, Van"
     console.log(person2.friends);    // 输出 "Mar, Court" ,能够看出修改person1的修改并不会影响到person2
     console.log(person1.friends === person2.friends); // 输出 false
     console.log(person1.sayName === person2.sayName); // 输出 true
    
    复制代码

除了以上几种模式还有动态原型模式寄生构造函数模式稳妥构造函数模式,但因为这些都不太经常使用,因此就不介绍了,有兴趣的小伙伴能够参考js红宝书第六章,里边介绍的很详细哦!

小结

这些是在阅读红宝书的过程当中,发现的一些小细节,或许还不够深刻,须要小伙伴们一块儿多积累多练习,你们一块儿学,一块儿交流进步才会更快哦,一块儿加油!持续更新中~

相关文章
相关标签/搜索