公有属性和私有属性指什么
function constructor() {1
var clure_v = "a"; // 闭包属性
var clure_f = function () {
// 私有方法
// code
console.log(clure_v);
};
this.private_v = "b"; // 私有属性
// 私有方法
this.private_f = function () {
console.log(this.clure_v,clure_v);
clure_v += "a";
clure_f();
};
}
constructor.prototype.public_v = "c";
constructor.prototype.public_f = function () {
console.log(this.clure_v, this.private_v, this.public_v);
};
console.log(constructor);
let c1 = new constructor();
console.log(c1);
console.log(c1.clure_v); //undefined
console.log(c1.private_v); //'b'
console.log(c1.public_v); //'c'
console.log(constructor.clure_v); //undefined
console.log(constructor.private_v); //undefined
console.log(constructor.public_v); //undefined
c1.private_f();
//undefined 'a' 'aa'
c1.private_f();
//undefined 'aa' 'aaa'
c1.public_f(); //undefined "b" "c"
console.log(c1.hasOwnProperty("clure_v")); //false
console.log(c1.hasOwnProperty("private_v")); //true
console.log(c1.hasOwnProperty("public_v")); //false
console.log("clure_v" in c1); //false
console.log("private_v" in c1); //true
console.log("public_v" in c1); //true
从上面的例子中我们可以得到
- JavaScript中的属性有内部定义不用this指向的属性,我们姑且称其为闭包属性,因为它对其属性起到一个保存和保护的作用,不会污染外部资源。
in
hasOwnProperty
都不能检测到他,不能使用this访问, - 另外有私有属性,就是在构造函数内部使用this指向定义的属性,该属性可以使用
in
hasOwnProperty
检测来判断其是否是一个对象的属性 - 公有属性,及原型链上的属性,该属性可以通过this访问,可以使用
in
,检测出来,不能使用hasOwnProperty
检测出来。
检测name是对象obj的属性
in 操作符
特点是无论是私有属性还是公有属性,只要有,就会返回true
hasOwnProperty
特点是,只有检测对象是其私有属性时才会返回true,否则返回false
JavaScript如何确定name是对象obj私有属性
obj.hasOwnProperty('name')
JavaScript如何确定name是对象obj公有属性
function getPubProperty(obj, attr) {
/*
第一种方法 使用 in 和 hasOwnProperty
已知,in可以用来判断公有和私有属性,hasOwnProperty可以用来判断私有属性,那么如果一个属性用in判断返回true,用hasOwnProperty判断返回false,就说明这个属性是公有属性
但是,需要注意的是:如果一个属性既是公有属性又是私有属性,判断就会出错
*/
/**
* 第二种方法,也是最正确的方法
* 就是检测原型上的属性,因为原型链上的属性都是公有的
*/
let proto = obj.prototype;
while (proto) {
if (proto.hasOwnProperty(attr)) {
return true;
}
proto = proto.prototype;
}
return false;
}
console.log(getPubProperty(c1, "public_v")); //true
console.log(getPubProperty(c1, "public_f")); //true
console.log(getPubProperty(c1, "private_v")); //false
对象遍历问题及解决方案
我们通常所用的遍历方式是 (for ... in ...
与for ... of ...
)
for ... in ...
for ... in ...
循环的特点是
- 对象的私有属性和公有属性都会被遍历到
- 但是不会遍历到对象的symbol属性
let sy = Symbol();
let obj = {
2: 2,
1: 1,
a: "a",
b: "a",
[sy]: "Symbol(sy)",
};
obj.c = "c";
Object.prototype.publica = "publica";
obj.d = "d";
for (const key in obj) {
console.log(key);
// if (obj.hasOwnProperty(key)) {
// console.log(key);
// }
//在上面的控制下只会输出
}
/**
* 1
* 2
* 'a'
* 'b'
* 'c'
* 'd'
* 'publica'
*/
for ... of ...
for ... of ...
循环的特点是
其循环对象必须要有具有Symbol.iterator
属性,调用这个接口就会返回一个遍历器对象。
原生部署了这个接口的数据结构如下
Array
Map
Set
String
TypedArray
- 函数的
arguments
对象 NodeList
对象
故而我们在使用for ... of ...
循环遍历对象的时候,需要使用中间件将对象转化为具有Symbol.iterator
接口的对象,这些中间件可以是如下几个:
-
Object.keys(obj)
返回一个数组,遍历对象私有属性,但是不遍历
Symbol
属性和公有属性console.log(Object.keys(obj));//["1", "2", "a", "b", "c", "d"]
-
Object.values(obj)
返回一个数组,里面是对象私有属性(不含Symbol属性)的值
console.log(Object.values(obj));[1, 2, "a", "a", "c", "d"]
-
Object.entries()
返回一个二维数组,里面是对象私有属性(不含Symbol属性)的['键','值']
console.log(Object.entries(obj)); /* 0: (2) ["1", 1] 1: (2) ["2", 2] 2: (2) ["a", "a"] 3: (2) ["b", "a"] 4: (2) ["c", "c"] 5: (2) ["d", "d"] */
-
Object.getOwnPropertyNames(obj)
返回一个数组
["1", "2", "a", "b", "c", "d"]
与
Object.keys(obj)
结果相同 -
Object.getOwnPropertySymbols(obj)
返回一个数组,遍历对象Symbol私有属性
[Symbol()]
-
Reflect.ownKeys(obj)
返回一个数组,遍历对象的包含Symbol属性的私有属性
["1", "2", "a", "b", "c", "d", Symbol()]
上面这几种遍历器方法都会遵循以下几个规则
- 首先遍历所有属性名为数值的属性,按照数字排序
- 其次遍历所有属性名为字符串的属性,按照生成时间排序
- 最后遍历所有属性名为
Symbol
值的属性,按照生成时间排序 - 先遍历私有属性,再遍历公有属性
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!