搜索
您的当前位置:首页正文

JavaScript中使用构造器创建对象无需new的情况说明_javascript技巧

2023-12-03 来源:微柏美食网

如下 代码如下:function Person(name, age) { this.name = name; this.age = age; } var p = new Person('lily', 20); 发现某些库代码中创建正则对象的方式无需new,这让人感到奇怪。如下 代码如下:var reg = RegExp('^he$'); 测试发现使用或不使用new,最后返回的都是正则对象,且typeof它们都是“object”。 代码如下: var reg1 = new RegExp('^he$'); var reg2 = RegExp('^he$'); reg1.test('he'); // true reg2.test('he'); // true console.log(typeof reg1); // object console.log(typeof reg2); // object 嗯,挺好,代码运行正常。 如果这样的话干脆就不写new了,这么还节省了代码量。其它类型也是这样吗?试试String/Number/Boolean。 代码如下:var str1 = new String(1); var str2 = String(1); var num1 = new Number('1'); var num2 = Number('1'); var boo1 = new Boolean(1); var boo2 = Boolean(1); console.log(typeof str1); // object console.log(typeof str2); // string console.log(typeof num1); // object console.log(typeof num2); // number console.log(typeof boo1); // object console.log(typeof boo2); // boolean 可以看到,与正则的情况不同。正则无论是否new,typeof后都是object。 但String/Number/Boolean类型,new的对象typeof返回是“object”,不new的typeof返回则是“string”。 即不适用new的情况可以将其它类型分别转化成字符串,数字和布尔类型。 好了,再回到篇头的那个Person类。即我们自己写的类可以不用new操作符生成对象吗? 代码如下:function Person(name, age) { this.name = name; this.age = age; } var p = Person('lily', 20); console.log(p); // undefined 返回undefined,很明显不行。因此想不用new的情况去创建Person实例是异想天开的。 如果非要实现呢?其实也行,如下 代码如下:function Person(name, age) { this.name = name; this.age = age; if (this===window) { return new Person(name, age); } } var p = Person('lily', 20); // object 稍微改造了下Person类。实际上内部区分了下Person是作为构造器还是函数执行。

小编还为您整理了以下内容,可能对您也有帮助:

javascript创建对象的几种模式介绍_基础知识

在js中有几种模式可以创建对象,通过对象操作所包含的属性与方法。

一般来说,构造函数名称的第一个字母为大写字母,非构造函数名称的第一个字母为小写字母,当然,构造函数与一般函数唯一的区别只是调用的方式不同而已,所以任何函数只要通过new来调用,那它就可以作为构造函数,若不通过new来调用,则与一般函数一样。

谈谈我对这几种模式的理解:

工厂模式:创建一个一般函数,在函数里创建一个Object对象,为这个对象增添属性与方法,同时赋予其值,最后返回对象。无法识别对象类型。

构造函数模式:创建构造函数,使用this来赋值,每当创建一个实例时,方法都被创建一次,而每个方法都执行相同的命令,这就多余了。这个缺点可以通过将方法放到全局环境中,但是,这样就没有封装性了。不过可以通过原型模式解决。

原型模式:每个函数都有一个prototype属性,该属性是一个指针,指向一个对象,该对象包含其函数创建的所有实例共享的属性与方法。

原型对象,构造函数以及实例之间的关系如下图:

图解:1:构造函数以及由构造函数创建的实例,它们的prototype属性都指向构造函数的原型对象。

2:构造函数的原型对象具有constructor属性,该属性指向构造函数。

3:构造函数的原型对象所包含的所有属性与方法可以被由构造函数所创建的所有实例共享。

使用对象字面量重写原型对象后,constructor则指向object构造函数,若需要其指向另一构造函数,则需修改原型对象的constructor属性的值,比如:constructor:Person,这样Person的原型对象即使被重写,原型对象的constructor仍指向Person构造函数。

当先创建实例时:若是直接添加属性或方法,实例可以访问。

若是重写原型对象,则构造函数的prototype指向新的原型对象,而之前创建的实例的prototype仍指向最初的原型对象,所以实例访问不到新的原型对象的新属性或和新方法。

原型对象包含的是共享的属性与方法,那么每个实例都拥有这些信息,这样实例之间就没有什么不同了,而且还不可以传参数,这不是我们所想要的。每个实例之间有共同的信息,又有不同的信息,所以我们可以组合使用构造函数模式与原型模式。

构造函数模式与原型模式的组合使用:

态原型模式:将的构造函数与其原型对象结合在一起,在构造函数里初始化原型,为其添加方法。

若该方法不存在,则将其添加到原型对象上,只在初始化原型时才执行,而且只执行一次。

寄生构造函数模式:与工厂模式类似,区别为:寄生构造函数模式为构造函数,通过new来创建实例。

稳妥构造函数模式:没有公共的属性,其方法不引用this的对象。创建实例时不使用new。只能通过方法访问属性(即传入的数据)。

js中不使用new实例化的方法

简单的说:
第一种是构造函数式,即通过new运算符调用构造函数Function来创建函数

第二种不是实例化,只是调用函数把返回值赋给变量。
扩展:

JavaScript 中并没有真正的类,但JavaScript 中有构造函数和new 运算符。构造函数用来给实例对象初始化属性和值。任何JavaScript 函数都可以用做构造函数,构造函数必须使用new 运算符作为前缀来创建新的实例。

new 运算符改变了函数的执行上下文,同时改变了return 语句的行为。实际上,使用new和构造函数很类似于传统的实现了类的语言:

// 实例化一个Me

var alice = new Me('alice', 18, 'Coder');
// 检查这个实例
assert( alice instanceof Me );
构造函数的命名通常使用驼峰命名法,首字母大写,以此和普通的函数区分开来,这是
一种习惯用法。
// 不要这么做!

Me('alice', 18, 'Coder'); //=> undefined
这个函数只会返回undefined,并且执行上下文是window(全局)对象,无意间创建了3个全局变量name,age,job。调用构造函数时不要丢掉new 关键字。
当使用new 关键字来调用构造函数时,执行上下文从全局对象(window)变成一个空的上下文,这个上下文代表了新生成的实例。因此,this 关键字指向当前创建的实例。尽管理解起来有些绕,实际上其他语言内置类机制的实现也是如此。

默认情况下,如果你的构造函数中没有返回任何内容,就会返回this——当前的上下文。

要不然就返回任意非原始类型的值.

js中不使用new实例化的方法

简单的说:
第一种是构造函数式,即通过new运算符调用构造函数Function来创建函数

第二种不是实例化,只是调用函数把返回值赋给变量。
扩展:

JavaScript 中并没有真正的类,但JavaScript 中有构造函数和new 运算符。构造函数用来给实例对象初始化属性和值。任何JavaScript 函数都可以用做构造函数,构造函数必须使用new 运算符作为前缀来创建新的实例。

new 运算符改变了函数的执行上下文,同时改变了return 语句的行为。实际上,使用new和构造函数很类似于传统的实现了类的语言:

// 实例化一个Me

var alice = new Me('alice', 18, 'Coder');
// 检查这个实例
assert( alice instanceof Me );
构造函数的命名通常使用驼峰命名法,首字母大写,以此和普通的函数区分开来,这是
一种习惯用法。
// 不要这么做!

Me('alice', 18, 'Coder'); //=> undefined
这个函数只会返回undefined,并且执行上下文是window(全局)对象,无意间创建了3个全局变量name,age,job。调用构造函数时不要丢掉new 关键字。
当使用new 关键字来调用构造函数时,执行上下文从全局对象(window)变成一个空的上下文,这个上下文代表了新生成的实例。因此,this 关键字指向当前创建的实例。尽管理解起来有些绕,实际上其他语言内置类机制的实现也是如此。

默认情况下,如果你的构造函数中没有返回任何内容,就会返回this——当前的上下文。

要不然就返回任意非原始类型的值.

Js创建对象额几种方式

第一种模式:工厂方式

说明:

1.在函数中定义对象,并定义对象的各种属性,,虽然属性可以为方法,但是建议将属性为方法的属性定义到函数之外,这样可以避免重复创建该方法

2.引用该对象的时候,这里使用的是 var x = Parent()而不是 var x = new Parent();因为后者会可能出现很多问题(前者也成为工厂经典方式,后者称之为混合工厂方式),不推荐使用new的方式使用该对象

3.在函数的最后返回该对象

4.不推荐使用这种方式创建对象,但应该了解。

缺点:①无法确定对象的类型(因为都是Object)。

②创建的多个对象之间没有关联。

第二种模式:构造函数方式

说明:

1.与工厂方式相比,使用构造函数方式创建对象,无需再函数内部重建创建对象,而使用this指代,并而函数无需明确return

2.同工厂模式一样,虽然属性的值可以为方法,扔建议将该方法定义在函数之外

3..同样的,不推荐使用这种方式创建对象,但仍需要了解。

缺点:①多个实例重复创建方法,无法共享。

②多个实例均不是同一个Function的实例。

第三种模式:原型模式

说明:

1.函数中不对属性进行定义

2.利用prototype属性对属性进行定义

3.同样的,不推荐使用这样方式创建对象

缺点:①无法传入参数,不能初始化属性值。

②如果包含引用类型的值时,改变其中一个实例的值,则会在所有实例中体现。

第四种模式:混合的构造函数,原型方式(推荐)

说明:

1.该模式是指混合搭配使用构造函数方式和原型方式

2.将所有属性不是方法的属性定义在函数中(构造函数方式)

将所有属性值为方法的属性利用prototype在函数之外定义(原型方式)

3.推荐使用这样方式创建对象

优点:构造函数共享实例属性,原型共享方法和想要共享的属性。可传递参数,初始化属性值。

第五种模式:动态原型方式

说明:

1.动态原型方式可以理解为混合构造函数,原型方式的一个特例

2.该模式中,属性为方法的属性直接在函数中进行了定义,但是因为

从而保证创建该对象的实例时,属性的方法不会被重复创建

3.推荐使用这种模式。

附:JS中多种方式创建对象详解

JS创建对象几种不同方法详解_javascript技巧

本文介绍了几种js创建对象的方法,分享给大家供大家参考,具体内容如下

1、工厂模式

弊端:没有解决对象的识别问题,即怎么知道一个对象的类型。

2、构造函数模式

与工厂模式相比:

1、没有显式的创建对象

2、直接将属性和方法赋给了this对象

3、没有return语句

要创建person的实例,必须使用new操作符,以这种方式调用构造函数实际上会经历4个步骤:

1、创建一个新对象

2、将构造函数的作用域赋给新对象

3、执行构造函数中的代码

4、返回新对象

创建自定义的构造函数可以将它的实例标识为一种特定的类型。

构造函数的缺点:

每个方法都有在每个实例上重新创建一遍。person1和person2都有一个sayName()的方法,但两个方法不是同一个Function实例。不同实例上的同名函数是不相等的。

创建两个完成同样任务的Function实例没有必要,而且还有this对象在,不需要在执行代码前就把函数绑定在特定对象上,可以像下面这样。

把sayName属性设置成全局的sayName函数,这样,由于sayName包含的是一个指向函数的指针,因此person1和person2对象就共享了同一个函数。

但是,如果对象需要定义很多方法,那么就要定义很多全局函数,自定义的引用类型也没有封装可言了。为了解决上述问题,引入原型模式。

3、原型模式

理解原型对象

我们创建的每个函数都有一个prototype属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。prototype是通过调用构造函数而创建的那个对象实例的对象原型,使用原型对象的好处是可以让所有对象实例共享它所包含的属性和方法。

首先,解析器会问实例person1是否有name属性,如果有,就返回。

如果没有,就继续去person1的原型中搜索name属性,如果有就返回。

如果没有,再继续向person1的原型的原型中搜索。

isPrototypeOf()确定实例和原型对象之间的关联

console.log(Person.prototype.isPrototypeOf(person1)); //true

Object.getPrototypeOf()返回的是[[prototype]]的值

console.log(Object.getPrototypeOf(person1));

//Person {name: “Yvette”, age: 26, job: “engineer”} 返回的是Person的原型对象。

console.log(Object.getPrototypeOf(person1) === Person.prototype)//true

console.log(Object.getPrototypeOf(person1).name);//”Yvette”

hasOwnProperty()方法可以检测一个属性是存在于实例中,还是存在于原型中,只有给定属性存在于实例中,才会返回true。

console.log(person1.hasOwnProperty(“name”));//false

原型与in操作符

有两种方式使用in操作符:单独使用和在for-in循环中使用。单独使用时,in操作符会在通过对象能够访问给定属性时返回true,无论该属性在于实例中还是原型中。

使用for in循环,返回的是所有能够通过对象访问的、可枚举的属性,其中既包括实例中的属性,也包括存在于原型中的属性。如果实例中的属性屏蔽了原型中不可枚举的属性,那么也会返回。IE9之前的版本实现上有一个Bug,屏蔽不可枚举属性的实例属性不会在for-in中返回。

在IE9之前的吧按本中没有log信息。尽管person实例中的toString()方法屏蔽了原型中的不可 枚举的toString();

原型简写

这导致了person1.constructor不再指向Person,而是指向了Object。如果constructor很重要,则需要特意将其设为适当的值,如:

但是这种方式会导致constructor属性变成可枚举。

如果想设置为不可枚举的(默认不可枚举),可以使用Object.defineProperty(Person.prototype, “constructor”, {

enumerable: false,

value: Person

});

原型的动态性

由于在原型中查找值的过程是一次搜索,因此我们对原型对象所做的任何修改都能够立即从实例上反映出来。

如果重写整个原型对象,情况就不一样了。调用构造函数时会为实例添加一个指向最初原型的[[prototype]]指针,而把原型修改为另外一个对象就等于切断了构造函数与最初原型之间的联系。实例中的指针仅指向原型,而不指向构造函数。

person.prototype指向的是原本的原型对象,而不会指向新的原型对象。

原型对象的问题

原型模式最大问题是由其共享的本性所导致的。

对于包含引用类型值的属性来说,问题较为突出

本意只想修改person1的friends,但是却导致person2的friends属性值也改变了。因此我们很少单独使用原型模式。

4、组合使用构造模式和原型模式

创建自定义类型的最常用的方式,就是组合使用构造函数模式与原型模式。构造函数模式用于定义实例属性,原型模式用于定义方法和共享的属性,这样每个实例都有自己的一份实例属性的副本,又同时共享着对方法的引用,最大限度的节省了内存。

微柏美食网还为您提供以下相关内容希望对您有帮助:

javascript中构造器调用模式中的this

其中的new 运算符,先产生了一个空对象{},然后生成一个this指针,将this指针指向这个空对象;运行构造函数时,就相当于“{}.a=0”一样的为这个对象动态添加属性。最后将这个生成好的对象付给MyQuo.2:this的意义,就是动态的指向当前代码所属的对象。function(){ return this.a; };如果不用new运...

Javascript中Number,parseIn和parseFloat的区别

1、parseFloat是个全局函数,不属于任何对象。2、如果在解析过程中遇到了正负号(+或-),数字(0-9),小数点,或者科学记数法中的指数(e或E)以外的字符,则它会忽略该字符以及之后的所有字符,返回当前已经解析到的浮点数.3、字符串首位的空白符会被忽略.如果参数字符串的第一个字符不能被解析成为数字,...

请说明javascript的继承机制和java继承机制的区别

2,构造继承:优点:可以实现多重继承,可以把子类特有的属性设置放在构造器内部。缺点:使用instanceof发现,对象不是父类的实例。3,实例继承:优点:是父类的对象,并且使用new构造对象和不使用new构造对象,都可以获得相同的效果。缺点:生成的对象实质仅仅是父类的实例,并非子类的对象;不支持多继承。...

JAVA俩类,用类的时候为什么Math类不需要new 呢

答:java是面向对象语言,简单的来说,就是化执行者为指挥者。而类的对象就是通过new关键字来创建对象的,再通过对象来引用成员变量和成员方法,这个深层的原因:和java在编译期对new转化的虚拟机指令有关系。这个不多说。2.Math类为什么不需要new?答:Math是JDK提供的一个工具类,1.6版本的申明源码...

构造器构造器

构造器在C#编程中起着关键作用,负责初始化类中的成员变量。主要有两种类型:实例构造器和静态构造器。实例构造器,当通过 new 关键字创建对象时会被调用,主要初始化实例变量,它们通常位于托管堆上,由.NET的CLR运行时管理。C#中的对象不能直接在栈上分配,除非显式声明,否则不会自动调用构造器。实例...

如何编写高质量JS代码(续)_javascript技巧

使用new操作符来调用User则视为构造函数。 代码如下:var u = new User("floraLam","123"); 与函数调用和方法调用不同的是,构造函数调用将一个全新的对象作为this变量的值,并隐式返回这个新对象作为调用结果。构造函数的主要职责是初始化该新对象。2.2 熟练掌握高阶函数高阶函数无非是那些将函数作为参数或返回值...

优化JavaScript脚本的性能的几个注意事项_基础知识

类型转换是大家常犯的错误,因为JavaScript是动态类型语言,你不能指定变量的类型。 1. 把数字转换成字符串,应用"" + 1,虽然看起来比较丑一点,但事实上这个效率是最高的,性能上来说: ("" +) > String() > .toString() > new String() 这条其实和下面的“直接量”有点类似,尽量使用编译时就能使用的内部...

javascript构造函数

全部由0到7的数字组成且以0开头的数字,js会自动按八进制进行处理,这样的话 010 由八进制转换为十进制就是 8 同理 0712 是 458 而 0719 则是 719 (因为9超过八进制的数字范围了,所以直接按十进制处理)

js的内置对象有哪些

1. `Array`对象:用于处理数组数据。2. `Date`对象:用于处理日期和时间。3. `Math`对象:用于执行数学运算和常数。4. `String`对象:用于处理字符串数据。5. `RegExp`对象:用于处理正则表达式和字符串匹配操作。此外,还包括像`Object`、`Function`等基本的构造器对象,它们作为创建对象的模板存在。

javascript构造函数是什么

javascript本身是没有类的概念,只有函数的概念。javascript的类实际上也是一个javascript的函数,在这个特殊的函数中间可以包含变量和其他javascript函数的引用。那么这个特殊的函数本身就是javascript所谓类的构造函数。

Top