深入理解自定义构造函数(javascript模式读书笔记)

深入理解自定义构造函数

在javascript中,有很多方法可以创建对象
  • 通过字面量的方式
  • 通过内置的构造函数
  • 通过自定义的构造函数

举个例子 : 这是一个最常见的自定义构造函数,实例化一个Person对象叫tianqin

	var Person = function(name){
    
    
			this.name = name;
			this.say = function(){
    
    
				return "I am" + "  "+this.name
			};
		};
		
		var tianQin = new Person("tianqin");
		tianQin.say();

输出结果
在这里插入图片描述
但是在使用 new 这个操作符的时候,函数内部发生了一系列隐式的行为

  • 创建一个空对象并且this变量引用了这个对象,同时继承了该对象的原型
  • 属性和方法被加入到this引用的对象中去
  • 新创建的对象用this所引用,并且最后隐式的返回this

伪代码表示这个过程

var Person = function(){
    
    
			var this = {
    
    
				//隐式的创建了一个this对象
			}
			this.name = name;
			this.say = function(){
    
    
				return "I am" + "  "+this.name
			};//这个过程其实是在给隐式创建的this对象添加属性和方法

			return this// 这里最后隐式的返回this(如果没有显示的返回其他对象,换句话说可以返回其他显示的对象)
		}

我们所看到的创建的一个空对象this,其实并不是空的,他已经从原型中继承了很多属性
其实是 var this = Object.create( Person.prototype )

值得注意的是:这里将say方法添加到了this中,这样做会导致在任何情况下调用的时候调用new Person()的时候都会在内存中创建一个新的函数,这种方法的效率是非常低下的
更好的方法是将方法添加到Person类的原型中


		Person.prototype.say = function() {
    
    
				return "I am" + "  " + this.name
		};

现在我们手动改变一下这个隐式的过程, 手动加上了一个自定义的对象

var Obj = function(){
    
    
			this.name = "tianQin";
			var myobj = {
    
    
		//就像隐式的生成this对象一样,这里手动的添加了一个新的自定义对象
			}
			myobj.name = "hlh";
			return myobj;
			//给新的对象添加了属性,最后返回这个新的对象
		}
		var obj = new Obj();
		console.log(obj.name);

看结果:输出了hlh
在这里插入图片描述
所以可以发现可以在构造函数中自由的返回任何对象

但是有没有想过一个问题,就是我们在实例化对象的时候,为什么要用new呢?
如果没有new会怎么样?
其实,没有new并不会导致语法错误,但可能会导致逻辑错误和意外行为的发生,可能会导致构造函数中的this指向了全局对象window。
举个例子:

	var Msg = function(){
    
    
			this.msg = "这是构造函数"
		}
		var newMsg = new Msg();  //这是使用了 new 的方式
		
		console.log(newMsg.msg);

		console.log(typeof newMsg);

		var newMsg2 = Msg(); //这是不使用 new 的方式
		// console.log(newMsg2.msg); 报错
		
		console.log(window.msg);

		console.log(typeof newMsg2);

我们来看一下输出结果:
从上至下依次是:
在这里插入图片描述
这种意外在ECMAscript5中得到了解决,并且在严格模式中,this不会指向全局变量

还有一种巧妙的办法叫做叫做使用一个命名公约这个命名可以是that 也可以是其他的

使用that改造上述代码:

var Msg = function(){
    
    
			var that = {
    
    };
			that.msg = "这是构造函数"
			return that;
		}
		var newMsg = new Msg();  //这是使用了 new 的方式

		console.log(newMsg.msg);

		console.log(typeof newMsg);

		var newMsg2 = Msg(); //这是不使用 new 的方式
		console.log(newMsg2.msg); 
		
		console.log(window.msg);

		console.log(typeof newMsg2);	

再来看一下输出:
在这里插入图片描述
发现使用new 和不使用 new这里都可以实例化一个对象

猜你喜欢

转载自blog.csdn.net/qq_43377853/article/details/108412821
今日推荐