constructor属性(CONSTRUCTOR)

http://www.itjxue.com  2023-01-26 04:23  来源:未知  点击次数: 

__attribute__详解及应用

attribute 是一个编译属性,用于向编译器描述特殊的标识、错误检查或高级优化。它是GNU C特色之一,系统中有许多地方使用到。 attribute 可以设置函数属性(Function Attribute )、变量属性(Variable Attribute )和类型属性(Type Attribute)等。

attribute 格式

其位置约束为:放于声明的尾部“;”之前。

函数属性可以帮助开发者把一些特性添加到函数声明中,从而可以使编译器在错误检查方面的功能更强大。

1. format

语法为 attribute ((format( NSString , F, A))),可以给被声明的函数加上类似printf或者scanf的特征,它可以使编译器检查函数声明和函数实际调用参数之间的格式化字符串是否匹配。format (archetype, m, n),第一个参数传递archetype指定为哪种类型,string-index指定格式化字符串的位置,n指定可变参数检查开始的位置。

在Objective-C 中通过使用 NSString 格式达到同样的效果,就像在 NSString +stringWithFormat: 和 NSLog() 里使用字符串格式一样

在使用NSLog函数进行输出时,如果我们传入的可变参数没有在格式化字符串中使用,编译器会提示警告,如下:

2.constructor与destructor

constructor属性可以指定函数在main函数执行之前进行调用,与之对应destructor可以指定某个函数在main函数执行结束之后再执行。这是一种非常强大的机制,在实际应用中也非常频繁,例如对以一个拥有模块化和路由功能的应用程序,可以通过这种方式来自动化的进行路由注册(无需手动调用),需要注意,constructor与destructor属性都可以设置一个优先级参数,优先级高的函数会先执行(0-100的优先级为系统保留)

3. unavailable

告诉编译器该方法不可用,如果强行调用编译器会提示错误。比如某个类在构造的时候不想直接通过init来初始化,只能通过特定的初始化方法()比如单例,就可以将init方法标记为unavailable;

实际上unavailable后面可以跟参数,显示一些信息,如:

4.objc_root_class

表示这个类是一个根类(基类),比如NSObject,NSProxy.

5.overloadable

用于c语言函数,可以定义若干个函数名相同,但参数不同的方法,调用时编译器会自动根据参数选择函数原型:

6. objc_subclassing_restricted

指明当前类型不能有子类,相当于final关键字,语法为 attribute ((objc_subclassing_restricted))。例如:

7. objc_requires_super

表示子类重写当前类的方法时,必须要调用super函数,否则会有警告。语法为 __attribute__((objc_requires_super)) ,例如:

8.objc_designated_initializer

指定内部实现的初始化方法,系统宏NS_DESIGNATED_INITIALIZER展开即为该指令,语法为 __attribute__((objc_designated_initializer)) 。例如:

当一个类存在方法带有NS_DESIGNATED_INITIALIZER属性时,它的NS_DESIGNATED_INITIALIZER方法必须调用super的NS_DESIGNATED_INITIALIZER方法。它的其他方法(非NS_DESIGNATED_INITIALIZER)只能调用self的方法初始化。

Object对象的属性

该属性返回对象类型原型的使用。

参数说明:

objectName:是对象的名称。

用prototype属性可以提供对象的类的一组基本功能。对象的新实例“继承”赋予该对象原型的操作。

例如,要为Array对象添加返回数组中最大元素值的方法是,声明该函数,将它加入Array.prototype,并使用它。

//结果:7,y保存数组x中的最大值

该属性表示创建对象的函数

参数说明:

object:必选项。是对象或函数的名称。

constructor属性是所有具有prototype的对象的成员。它们包括除Global和Math对象以外的所有js固有对象。constructor属性保存了对构造特定对象实例的函数的引用。例如:

//结果: true

判断一个对象是否属于某一类

javascript中检测对象的类型的运算符有:typeof、constructor、instanceof。

typeof:typeof是一个一元运算符,经常用来检测一个变量是不是最基本的数据类型,返回结果是一个说明运算数类型的字符串。如:"number","string","boolean","object","function","undefined"(可用于判断变量是否存在)。 但 typeof 的能力有限,其对于Date、RegExp、Array类型返回的都是"object"。所以它只在区别对象和原始类型的时候才有用。要区一种对象类型和另一种对象类型,必须使用其他的方法。

instanceof 运算符:用来判断某个构造函数的 prototype 属性所指向的对象是否存在于另外一个要检测对象的原型链上。简单说就是判断一个引用类型的变量具体是不是某种类型的对象,instanceof 运算符要求其左边的运算数是一个对象,右边的运算数是对象类的名字或构造函数。

如果 object 是 class 或构造函数的实例,则 instanceof 运算符返回 true。如果 object 不是指定类或函数的实例,或者 object 为 null,则返回 false。instanceof方法可以判断变量是否是数组类型。

constructor 属性: JavaScript中,每个对象都有一个constructor属性,它引用了初始化该对象的构造函数,常用于判断未知对象的类型。如给定一个求知的值 通过typeof运算符来判断它是原始的值还是对象。如果是对象,就可以使用constructor属性来判断其类型。

如何使用 constructor 属性:

输出:

Object.prototype.toString.call():该方法是目前为止发现的判断一个对象类型的最好的办法。

JS中的constructor属性是什么?

首先看一段简单的js代码: //定义对象myvar var c = myvar.constructor; switch(c) { case Date: alert("This is a Data Type"); break; case Array: alert("This is a Array Type"); break; case String: alert("This is a String Type"); break; case Boolean: alert("This is a Boolean Type"); break; case Number: alert("This is a number Type"); break; } 在代码前段分别定义不同变量类型,返回对应效果如下: myvar=1 This is a number Type myvar=“a” This is a String Type myvar=true This is a Boolean Type myvar=new Date() This is a Date Type myvar= new Array("a","b","c","d") This is a Array Type 从上面代码可以看出 constructor属性可以返回代码的数据类型; 但是有经验的朋友可能会发现,这中通过constructor属性获取类型的方法很容易被修改,做个效果看看: var myvar= new Array("a","b","c","d"); function A() {} myvar.constructor =A; var c = myvar.constructor; switch(c) { case Date: alert("This is a Data Type"); break; case Array: alert("This is a Array Type"); break; case String: alert("This is a String Type"); break; case Boolean: alert("This is a Boolean Type"); break; case Number: alert("This is a number Type"); break; default: alert("This is a UnKnown Type"); break; } 大家估计下应该输出什么? This is a UnKnown Type! 那该怎么来防止那,本人做了简单的测试发现,可以通过这样来防止; var myvar= new Array("a","b","c","d"); function A() {} myvar.constructor =A; /*var c = myvar.constructor; */ var c = Object.prototype.toString.call(myvar).toString().replace(/object /,""); switch(c) { case "[Date]": alert("This is a Data Type"); break; case "[Array]": alert("This is a Array Type"); break; case "[String]": alert("This is a String Type"); break; case "[Boolean]": alert("This is a Boolean Type"); break; case "[Number]": alert("This is a number Type"); break; default: alert("This is a UnKnown Type"); break; } 测试完毕

js中new 生成对象时默认有个constructor属性吗?

js中所有的对像都继承了Object 对像的属性,Object 对像有这个constructor属性,那么所有的对像都有这个属性,包括你自己创建的。 Math对像除外。

js中函数的prototype.constructor是指向函数本身,它有什么用

js中函数的prototype.constructor是指向函数本身,它有什么用?修改后会有什么影响?

1,首先constructor并不是都可写,对于原始值(如1,true 或 "test"),该属性为只读。

2,constructor指向的是函数本身,这里的指向我们如果修改了,是会影响到所有通过此构造器生成的实例的,要理解这里就要去看一些javascript prototype原型方面的介绍,prototype的作用是继承和共享属性用的,他的作用范围会影响所有实例。

3,依赖constructor的检测是很不安全的,因为他随时可能被修改或者覆盖。

相关知识链接

------

constructor - JavaScript

ECMAScript Language Specification

-----

可能某些同学不太理解,我来个实际例子来解释一下好了:

constructor属性的出现从它本身的作用就可以理解,它有2个作用:

1,拿到实例的构造器。

比如我拿到了一个实例,想对其的某些原型方法进行修改(很危险),但是其实是可以通过拿constructor再改写这个constructor的prototype来影响所有实例的。(动态修改,这个时候你一定要知道你在做什么。。否则真的很危险)

2,对比两个实例是否是同一类型(native constructor)。

"string".constructor === String.prototype.constructor

再或者:

function test(){}

test1 = new test();

test2 = new test();

我们有些时候是需要判断test1和test2是否为同一类型的(比如我们确定是同一类型,那么他们应该就会有共有的prototype了吧?太天真了,这都是不靠谱。。)

-------

最后,如果你不知道你在做什么或者写什么,请先弄明白你需要干什么,再问为什么……否则,真的很危险……

作者:小爝

链接:

来源:知乎 ? 望给予采纳

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

(责任编辑:IT教学网)

更多

推荐PowerPoint文章