`
i_love_sc
  • 浏览: 35877 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
社区版块
存档分类
最新评论

以未知数量的参数调用构造函数

阅读更多

    场景

 

    你会收到一个的构造函数ctor,以及一个数组args,对于每个ctor,args长度不定。如何能够通用的构造一个实例呢?

    简单而不用思考的方法:

 

var buildInstance = function(ctor, args) {
	if (args.length == 0) {
		return new ctor();
	}
	if (args.length == 1) {
		return new ctor(args[0]);
	}
	if (args.length == 2) {
		return new ctor(args[0], args[1]);
	}
	if (args.length == 3) {
		return new ctor(args[0], args[1], args[2]);
	}
};

     It works.

 

     自己实现“new”

 

     但是聪明而又懒惰的程序员显然不会满足用这种方式写出的代码,它太不时髦了。

     我们考虑一下new ctor的时候,程序做了什么?

     1、构造了一个新的object对象o

     2、使o的原型指向ctor的prototype

     3、对o调用了ctor

 

     了解了以上原理之后,我们也可以自己来实现“new”,代码如下:

 

var projection = function(o) {
	var F = function() {};
	F.prototype = o;
	return new F();
};

var buildInstance = function(ctor, args) {	
	var proto = projection(ctor.prototype);
	ctor.apply(proto, args);
	return proto;
};

 

   我们来测试一下

 

var MockClass = function() {
	this.args = arguments;
};		
	
MockClass.prototype.log = function() {
	console.log(this.args);
}


var mock1 = buildInstance(MockClass, [1,2]);
mock1.log(); // [1,2]
var mock2 = buildInstance(MockClass, [1,2,3]);
mock2.log(); // [1,2,3]

     it works!

 

 

     利用Function.prototype泛化

 

     作为一个肯动脑筋的程序员,我觉得还能再进一步,这个方法添加到Function.prototype

Function.prototype.buildInstance = 	function(args) {	
	var proto = projection(this.prototype);
	this.apply(proto, args);
	return proto;
};

     然后我们就可以这样调用了

var mock1 = MockClass.buildInstance([1,2]);
mock1.log(); // [1,2]
var mock2 = MockClass.buildInstance([1,2,3]);
mock2.log(); // [1,2,3]

     太赞了!

 

 

分享到:
评论

相关推荐

    C++面向对象程序设计答案

    当一个对象被初始化为另一个已存在的同一类对象的副本时,拷贝构造函数会被调用。它负责深拷贝或浅拷贝对象的所有成员。 7. 运算符重载 C++允许我们为现有的运算符赋予新的含义,以适应类的需求。例如,我们可以...

    MoreEffectiveC++

    - **定义**:new用于在堆上分配内存并调用构造函数;delete用于释放由new分配的内存并调用析构函数。 - **应用场景**: - 在需要动态分配内存时使用new; - 释放内存时使用相应的delete。 - **注意事项**: - new...

    5.逆向C++(中文版).pdf

    - **构造函数与析构函数**:识别构造函数的一个常见方法是在类实例化后立即调用的函数。而析构函数通常在对象生命周期结束前被调用。 ##### B. 识别类 - **类的识别**:识别类的关键在于找到类的定义及其成员。...

    JavaScript中的apply和call函数详解_.docx

    `apply`的一个优势在于可以动态地传递参数,即使参数数量未知,只需将参数放入数组即可: ```javascript function g(object, func, argsArray) { func.apply(object, argsArray); } var o = {x : 15}; var f1 = ...

    高质量C++编程指南

    - **参数的规则**:参数的数量和类型应该经过精心设计,避免过多的参数使得函数调用变得复杂。 - **返回值的规则**:明确函数的返回值意义,并确保返回值与函数的功能一致。 - **函数内部实现的规则**:保持函数内部...

    计算机二级C++强化测试.pdf

    - 拷贝构造函数通常接收一个同类型对象的引用作为参数,用于创建新对象的副本。 16. **派生类与基类对象的关系**: - 派生类的对象可以赋值给基类的对象,可以初始化基类的引用,其地址也可以赋给指向基类的指针...

    C++复习题带答案

    31. **转换构造函数**:具有转换功能的构造函数可以只有一个参数,用于将该类型转换为当前类类型。 32. **多继承构造函数执行顺序**:多继承时,派生类构造函数的执行顺序依赖于定义时基类的顺序。 33. **C++特性*...

    林锐 编程指南

    - **构造和析构的次序**:解释构造函数和析构函数调用顺序的影响因素。 - **类String示例**:通过具体实例说明构造函数和析构函数的应用。 - **拷贝构造函数与赋值函数的重要性**:强调正确实现拷贝构造函数和赋值...

    C#错误编码详解很有用!

    **解决方案**: 确认构造函数调用时提供了所有必需的参数。 #### 错误 CS0121 **描述**: 方法重载时参数匹配失败。 **解决方案**: 调整参数列表以匹配正确的重载方法。 #### 错误 CS0122 **描述**: 成员访问受限。 ...

    C++复习题库电子版汇总(王坦).doc

    - 实参可以是常量、变量或表达式,但在调用函数时,必须确保实参的数量和类型与形参相匹配。 - 形参不能是常量,因为它们需要用来接收实参的值。 - 形参和实参的类型和个数必须一致,除非使用了类型转换或者函数...

    javascript

    2. **`arguments`对象**:允许函数访问传入的所有参数,即使参数数量未知。 3. **`callee`与`caller`属性**:`callee`属性可用于递归调用,而`caller`属性则可以获取调用当前函数的父函数。 4. **`apply`与`call`...

    规划,目标函数,最值求解

    例如,在生产计划问题中,目标函数是max f=70x1+120x2,约束条件包括9x1+4x2≤3600等,我们可以设置相应的参数调用`linprog`来找到最优生产数量x1和x2。 对于投资问题和运输问题,也可以类似地构建目标函数和约束...

    Java大赛选拔试题

    正确答案是D,尽管实际上题目中的类构造函数只接受一个参数,这里提供了一个额外的参数,但从题目描述来看,应该是希望考察构造函数的调用方式。 4. **类的访问控制修饰符** - 正确答案: B.final - **知识点**:...

    kotlin in action

    - **`vararg`参数**:表示可变参数列表,允许调用者传递任意数量的参数。 - **`infix`关键字**:用于定义可使用操作符语法调用的函数。 **3.5 使用字符串和正则表达式** - **字符串模板**:Kotlin支持使用`${}`...

    matlab开发-getgooglestreetviewlocvvarargin

    这在处理具有可变数量或未知数量输入的函数时非常有用。 3. **谷歌街景服务**: 谷歌街景服务是Google Maps API的一部分,提供了获取全球各地高清街景图像的能力。通过该服务,开发者可以集成街景图像到自己的应用...

    java this的应用方法解析

    总结来说,`this`关键字在Java中起着至关重要的作用,它可以帮助我们清晰地表示当前对象的引用,特别是在处理重名变量、调用构造函数、返回当前对象以及在内部类中引用外部类成员时。正确理解和使用`this`能够提升...

    python面试题.docx

    `*args`接收一个元组,`**kwargs`接收一个字典,这样函数就能处理未知数量的参数。 Python是区分大小写的,因此变量名、函数名等标识符的大小写必须保持一致。Python的标识符命名规则规定,标识符必须以字母或...

    “桂林高新杯”软件设计大赛第二届C#试题及解答

    - **选项D**:构造函数可以带有参数。这些参数用于给新创建的对象提供初始值。 #### 题目2:预处理器指令`#region`和`#endregion` - **选项A**:`#region`和`#endregion`不是用来注释代码,而是用于标记一段代码...

    第12章 动态内存1

    - 对于内置类型,`new`分配的内存默认不会初始化,而类类型对象会调用默认构造函数进行初始化。 - 初始化动态分配的对象可以使用括号或花括号,如`new int(5)`或`new int{5}`。 总的来说,动态内存管理是C++编程中...

Global site tag (gtag.js) - Google Analytics