面向对象-扩展(上)

199 阅读8分钟

这是我参与8月更文挑战的第16天,活动详情查看:8月更文挑战

一、面向对象-扩展-Object静态方法(了解)

说明: 其中只有Object.assign()Object.keys() / Object.values() 会用的多一点,其他很少用的做个了解即可。

01-Object.is()

作用: 严格比对两个变量是否相等

注意: 不同于==和=== MDN文档是这样描述的,如果满足以下条件则两个值相等:

  • 都是 undefined

  • 都是 null

  • 都是 true 或 false

  • 都是相同长度的字符串且相同字符按相同顺序排列

  • 都是相同对象(意味着每个对象有同一个引用)

  • 都是数字且

    • 都是 +0
    • 都是 -0
    • 都是 NaN
    • 或都是非零而且非 NaN 且为同一个值.

使用:Object.is(value1, value2);

比如:

Object.is(+0, -0);  // false
Object.is(NaN, NaN); // true
Object.is(0, 0); // true

02-Object.assign()

拷贝源对象所有属性到目标对象中

使用:Object.assign(目标对象, 源对象1, 源对象2, 源对象3...);

如果存在重复属性, 按照顺序, 则后者会把前者覆盖;

const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, d: 4 };

const Target = Object.assign(obj1, obj2);

console.log(obj1); // { a: 1, b: 3, c: 4 }

console.log(Target); // { a: 1, b: 3, c: 4 }

03-Object.keys()-values()

1. Object.keys()

获得指定对象所有的key,返回一个所有元素为字符串的数组

var obj = { a: 1, b: 2, c: 3 };
var res = Object.keys(obj); 
console.log(res);  // ['a', 'b', 'c']

2. Object.values()

获得指定对象所有的value,返回一个数组,其元素是在对象上找到的可枚举属性值。

var obj = { a: 1, b: 2, c: 3 };
var res = Object.values(obj);
console.log(res);  // [1, 2, 3]

不包含原型属性,可以获取静态属性(自己的),实例对象进行获取的时候

04-Object.getOwnPropertyNames()

获得指定对象所有的key

var arr = ["a", "b", "c"];
console.log(Object.getOwnPropertyNames(arr));  //  ["0", "1", "2", "length"]

不包含原型属性,可以获取静态属性(内置 + 自己)

05-Object.getOwnPropertyDescriptor()

获得对象中某个实例属性描述信息(是否可以配置,枚举,值,是否可以重写)。

var obj = {name: 'jack', age: 18};  // 定义一个对象
var res = Object.getOwnPropertyDescriptor(obj, 'name'); // 获取指定对象的指定属性描述
console.log(res);  // 具体的描述信息

具体的描述信息如下:

  • configurable:true ----- 是否是可以配置的(能不能删除属性或者是修改这个配置本身)
  • enumerable:true ----- 是否是可以枚举的(在for..in循环中是否能够遍历出来|keys())
  • value:"jack" ----- 属性对应的
  • writable:true ----- 是否是可重写

06-Object.getOwnPropertyDescriptors()

这个唯一的区别就是获取一个实例中所有的属性描述信息,getOwnPropertyDescriptor是获取某一个,所有要传2个参数。

var obj = {name: 'jack', age:18};
console.log(Object.getOwnPropertyDescriptors(obj));

image.png

返回值: 键值对

  • 键:属性名称
  • 值:属性描述信息

07-Object.defineProperty()

用来设置属性的描述信息(修改已有的属性|新增属性),并返回此对象。

var obj = {
  name: 'jack',
  age: 18
};

// 定义一个对象
// 配置属性描述  
Object.defineProperty(obj, 'name', {
  value: 'rose', // 控制属性取值
  writable: false, // 控制是否允许重写 false: 该属性值无法修改
  enumerable: false, // 是否可被枚举, for in 遍历, 不会被遍历到
  configurable: false // 是否可配置 如果设置为false, 则无法进行二次配置修改
})

// 设置新的值
obj.name = 'Tom'; 

console.log(obj) // {age: 18, name: "rose"}  因为设置了不可写,所以Tom不生效

注意以下3点

  • 如果定义的属性不存在, 则会新增这个属性; 如果存在, 则修改
  • 修改已有的属性,默认情况下这三个值是true
  • 新增加属性,默认情况下,这三个属性的值都是false

08-Object.defineProperties()

作用:批量设置属性描述信息

var obj = {name: 'jack', age: 18};
Object.defineProperties(obj, {
        'name': {
            writable: false  // 控制是否允许重写
        },
        'age': {
            enumerable: false  // 是否可被枚举
        }
});

09-Object.create()

创建一个新对象newObj,并且设置newObj的原型对象为sourceObj,可用于原型式继承

const person = {
  isHuman: false,
  printIntroduction: function() {
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
  }
};

const me = Object.create(person);

me.name = 'Matthew'; // "name" is a property set on "me", but not on "person"
me.isHuman = true; // inherited properties can be overwritten

me.printIntroduction();
// expected output: "My name is Matthew. Am I human? true"

兼容代码

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

10-Object.getPrototypeOf()

获得某个对象的原型对象,等同于p.__proto__,只不过这个属性属于非标准属性, 仅仅作调试用。

const prototype1 = {};
const object1 = Object.create(prototype1);

console.log(Object.getPrototypeOf(object1) === prototype1); // true

11-Object.setPrototypeOf()

设置一个指定的对象的原型 ( 即, 内部[[Prototype]]属性)到另一个对象或  null

详情请查看MDN:Object.setPrototypeOf()

var dict = Object.setPrototypeOf({}, null);

二、面向对象-扩展-Object.prototype

01-hasOwnProperty()

检测对象中是否存在某个实例属性,这个可以用于当你只想拿对象身上的属性而不是原型链上的属性的时候

const object1 = {};
object1.property1 = 42;

console.log(object1.hasOwnProperty('property1'));  // true

console.log(object1.hasOwnProperty('toString'));  // false

console.log(object1.hasOwnProperty('hasOwnProperty'));  // false

02-isPrototypeOf()

用于测试(判断)一个对象是否存在于另一个对象的原型链上(会判断整条原型链)。如果存在,返回true,否则返回false

function Cat(){
	this.name = "花花";
	this.sex = "girl";

	this.sayHello = function(){
            console.log("我叫" + this.name);
	};
}

var c =  new Cat();
console.log( Cat.prototype.isPrototypeOf(c) ); // true

var obj = {
    weight: "2kg",
    sayHi: function(){
        console.log("你好,我是" + this.sex);
    }
};

// 使用对象obj覆盖Cat本身的prototype属性
Cat.prototype = obj;

var c2 =  new Cat();
console.log( obj.isPrototypeOf(c2) ); // true

10.png

03-propertyIsEnumerable()

判断该属性是否可枚举 如果是可以枚举的,那么在使用for..in循环的时候可以打印出来

//设置属性
Object.defineProperty(obj,"age",{
    enumerable:false,
});

04-toString()

返回一个对当前对象的字符串描述信息,并非一定是该对象的字符串形式

  • ① object类型的对象 返回的是 [obejct Object]
  • ② 其他对象类型如函数 | 数组 ,返回对应的字符串形式
  • ③ Number类型 可以传递参数(进制) 不传递参数:默认是十进制
var obj = { name: 'jack' };
obj.toString(); // "[object Object]"

var arr = ['1', '2', '3']
arr.toString(); // "1,2,3"

var fun = function () {}
fun.toString(); // "function () {}"

使用 toString() 检测对象类型

可以通过 toString() 来获取每个对象的类型。为了每个对象都能通过 Object.prototype.toString() 来检测,需要以 Function.prototype.call() 或者 Function.prototype.apply() 的形式来调用,传递要检查的对象作为第一个参数,称为 thisArg

var toString = Object.prototype.toString;

toString.call(new Date); // [object Date]
toString.call(new String); // [object String]
toString.call(Math); // [object Math]

//Since JavaScript 1.8.5
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]

05-valueOf()

JavaScript调用valueOf方法将对象转换为原始值。你很少需要自己调用valueOf方法;当遇到要预期的原始值的对象时,JavaScript会自动调用它。

不同类型对象的valueOf()方法的返回值

对象返回值
Array返回数组对象本身。
Boolean布尔值。
Date存储的时间是从 1970 年 1 月 1 日午夜开始计的毫秒数 UTC。
Function函数本身。
Number数字值。
Object对象本身。这是默认情况。
String字符串值。
 Math 和 Error 对象没有 valueOf 方法。
// Array:返回数组对象本身
var array = ["ABC", true, 12, -5];
console.log(array.valueOf() === array);   // true

// Date:当前时间距1970年1月1日午夜的毫秒数
var date = new Date(2021, 8, 13, 14, 00, 23, 200);
console.log(date.valueOf());   // 1631512823200

// Number:返回数字值
var num =  15.26540;
console.log(num.valueOf());   // 15.2654

// 布尔:返回布尔值true或false
var bool = true;
console.log(bool.valueOf() === bool);   // true

// new一个Boolean对象
var newBool = new Boolean(true);
// valueOf()返回的是true,两者的值相等
console.log(newBool.valueOf() == newBool);   // true
// 但是不全等,两者类型不相等,前者是boolean类型,后者是object类型
console.log(newBool.valueOf() === newBool);   // false

// Function:返回函数本身
function foo(){}
console.log( foo.valueOf() === foo );   // true
var foo2 =  new Function("x", "y", "return x + y;");
console.log( foo2.valueOf() );


// Object:返回对象本身
var obj = {name: "张三", age: 18};
console.log( obj.valueOf() === obj );   // true

// String:返回字符串值
var str = "testString";
console.log( str.valueOf() === str );   // true

// new一个字符串对象
var str2 = new String("testString");
// 两者的值相等,但不全等,因为类型不同,前者为string类型,后者为object类型
console.log( str2.valueOf() === str2 );   // false

三、面向对象-扩展-基本包装类型

问:什么是基本包装类型?

答:把基本数据类型, 包装成为对象类型

一共有3大类:Boolean类型,Number类型,String类型

true|false
        new Boolean(true)
        new Boolean(false)
666
        new Number(666);
'jack'
        new String('jack');

1、boolean  布尔对象类型

创建Boolean对象

boolean对象用于转换一个不是Boolean类型的值转换为Boolean类型值(true或者false)。

var Boolean = new Boolean ();

实例方法

1. Boolean.prototype.toString()

toString()  方法返回指定的布尔对象的字符串形式。

const flag = new Boolean(true);

console.log(flag.toString()); // true

2. Boolean.prototype.valueOf()

valueOf()  方法返回一个Boolean对象的原始值

const x = new Boolean();

console.log(x.valueOf()); // false

2、number  数字对象类型

创建Number对象

var num = new Number(value);

Number 对象主要用于:

  • 如果参数无法被转换为数字,则返回 NaN
  • 在非构造器上下文中 (如:没有 new操作符),Number 能被用来执行类型转换。

属性

这里列举其中一个,详情可参考MDN

Number.MAX_VALUE

Number.MAX_VALUE 属性表示在 JavaScript 里所能表示的最大数值。

因为 MAX_VALUE 是 Number 对象的一个静态属性,所以你应该直接使用Number.MAX_VALUE ,而不是作为一个创建的 Number 实例的属性。

下面的代码求两个数值的乘积。如果结果小于等于 MAX_VALUE,则调用 func1 函数;否则,调用 func2 函数。

if (num1 * num2 <= Number.MAX_VALUE) {
   func1();
} else {
   func2();
}

3、string 字符串对象类型

创建

var str = new String(value);

基本字符串和字符串对象的区别

这里引用MDN中的详细介绍:

字符串字面量 (通过单引号或双引号定义) 和 直接调用 String 方法(没有通过 new 生成字符串对象实例)的字符串都是基本字符串。JavaScript会自动将基本字符串转换为字符串对象,只有将基本字符串转化为字符串对象之后才可以使用字符串对象的方法。当基本字符串需要调用一个字符串对象才有的方法或者查询值的时候(基本字符串是没有这些方法的),JavaScript 会自动将基本字符串转化为字符串对象并且调用相应的方法或者执行查询。

var str1 = "foo";
var str2 = new String(str1);

console.log(typeof str1); //  string
console.log(typeof str2);  //  object

四、结语

码字不易,如果觉得对你有帮助,觉得还不错的话,欢迎点赞收藏~

当然由于是个人整理,难免会出现纰漏,欢迎留言反馈。