javascript 中new操作符

“new”在js中new作为一个关键字的存在,这是无可厚非的,当然,我们在编程的时候,我们往往会想到面向对象编程,这不,使用这个关键字就能创建对象啦

js不同于其他动态语言,不需要编译,这种静态语言的书写方式也是有所不同的,不过,根据现在的发展,在es6之后,js语言愈来愈接近其他后台语言形式了比如出现了class类的概念

在js中,任何定义的函数function都可以使用new操作符来实现构建一个构造函数,通常我们队构造函数与普通函数区别,我们通常会把构造函数名首字母大写eg:

var Vehicle = function () {
  this.price = 1000;//函数内部使用的this关键字代表所要生成的对象实例
  console.log( this.constructor===Vehicle ) //true
}

使用new操作符,即会返回该构造函数的一个实例对象,当然,作为一个函数(构造函数同样也是一个函数)当然也是可以携带参数的,并且个数理论上不受限制,当然我们一般在处理函数参数的时候尽量的控制在5个以下eg:var Foo = function(pram1,pram2,...){} 具体函数中有携带几个参数,其实我们可以通过Foo.length来获取到,这length属性不是说传递几个参数,而是表示该函数自带几个参数,当然你传递多少个参数都是可以的,在函数内部,你可以通过arguments对象来操作传递过来的参数,例如Date函数,在构建实例的时候可以传递不同参数,这种方式在典型的面向对象语言中叫做重载。创建构造函数在函数名后面紧接括号,不携带参数时是可以不带的,但我们一般习惯性的还是加上括号eg:
var f = new Foo();//推荐写法
var f = new Foo;//一般不推荐,但是两种写法是相同的

在创建构造函数的实例时,不要忘了关键字new,不然将不会得到想要的结果eg:
var Foo = function (){
this.a = 1;
};
var f = Foo();
v // 输出undefined,这是因为在执行Foo()的时候Foo函数没有返回值,函数若没有返回值的情况下默认将会返回undefined
a // 输出1,这是因为直接这样以调用Foo函数的形式,这样会使得this指向到全局,即window下所以Foo中的this.a也就创建在了window下面

上面代码注意了,若是在严格模式下,直接以执行函数方式来调用构造函数,js会抛出异常eg:
function Foo(){
'use strict';
this.a = 1;
}
Foo(); // Uncaught TypeError: Cannot set property 'a' of undefined,这是因为在直接执行Foo()时,此时的this为undefined,故无法对undefined下设置属性值

要想不报错的运行下去,我们可以在构造函数内部通过instanceof判断,是否使用new命令,如果发现没有使用,则直接返回一个实例对象eg:
if(!(this instanceof Foo)){
return new Foo()
}


下面我们在说说new操作符的运行机制大致分为以下几步
1、创建一个空对象,作为将要返回的对象实例。
2、将这个空对象的原型,指向构造函数的prototype属性。
3、将这个空对象赋值给函数内部的this关键字。
4、开始执行构造函数内部的代码。
实际上在构造函数内部都会有一个return语句,在使用new操作符的时候,在构造函数内部的this会指向一个新生产的空对象,接下来的所有this操作,都将对应在新生成的空对象上,然后再返回这个对象,便是实例对象,但是,一旦在构造函数中定义了return并且return后紧接的是一个对象,那么new操作后返回的实例就是构造函数中return的对象,若不是对象,则会忽略该return后面的eg:


var F = function(){
  var o = {a:1};
  return o;
}
var f = new F()
f //{a: 1}

var F = function(){
  this.a = 2;
  return 'hello world';
}
var f = new F()
f //{a:2}
 一个简化版的new操作流程 function _new( constructor, params) {
  // 将 arguments 对象转为数组
  var args = [].slice.call(arguments);
  // 取出构造函数
  var constructor = args.shift();
  // 创建一个空对象,继承构造函数的 prototype 属性
  var context = Object.create(constructor.prototype);
  // 执行构造函数
  var result = constructor.apply(context, args);
  // 如果返回结果是对象,就直接返回,否则返回 context 对象
  return (typeof result === 'object' && result != null) ? result : context;
} 实际上就是在内部创建一个新的空对象,然后把构造函数的所有属性都附加到新添加的空对象上,然后再判断性返回结果

在构造函数中有个关键字target,如果当前函数是通过new操作符来调用,new.target指向当前函数,否则new.target将会是undefined
创建实例还可以通过Object.create来创建,像上面的new操作流程示意就是通过Object.create来实现

PHP Warning: curl_exec() has been disabled for security reasons in /home/ftp/f/free49568/wwwroot/wp-content/themes/Variant/functions.php on line 490 百度已收录
分享