资讯专栏INFORMATION COLUMN

JS整理知识点5.10

Acceml / 3320人阅读

摘要:将这个空对象的原型,指向构造函数的属性。构造函数内部,指的是一个新生成的空对象,所有针对的操作,都会发生在这个空对象上。构造函数之所以叫构造函数,就是说这个函数的目的,就是操作一个空对象即对象,将其构造为需要的样子。

toString() 的应用:判断数据类型
为了得到类型字符串,最好直接使用Object.prototype.toString方法。通过函数的call方法,可以在任意值上调用这个方法,帮助我们判断这个值的类型。

**Object.prototype.toString.call(value)**

不同数据类型的Object.prototype.toString方法返回值如下。
数值:返回[object Number]。
字符串:返回[object String]。
布尔值:返回[object Boolean]。
undefined:返回[object Undefined]。
null:返回[object Null]。
数组:返回[object Array]。
arguments 对象:返回[object Arguments]。
函数:返回[object Function]。
Error 对象:返回[object Error]。
Date 对象:返回[object Date]。
RegExp 对象:返回[object RegExp]。
其他对象:返回[object Object]。

可以写出一个比typeof运算符更准确的类型判断函数。

var type = function (o){
  var s = Object.prototype.toString.call(o);
  return s.match(/[object (.*?)]/)[1].toLowerCase();
};

type({}); // "object"
type([]); // "array"
type(5); // "number"
type(null); // "null"
type(); // "undefined"
type(/abcd/); // "regex"
type(new Date()); // "date"

new 命令的原理
使用new命令时,它后面的函数依次执行下面的步骤。

创建一个空对象,作为将要返回的对象实例。

将这个空对象的原型,指向构造函数的prototype属性。

将这个空对象赋值给函数内部的this关键字。

开始执行构造函数内部的代码。

构造函数内部,this指的是一个新生成的空对象,所有针对this的操作,都会发生在这个空对象上。构造函数之所以叫“构造函数”,就是说这个函数的目的,就是操作一个空对象(即this对象),将其“构造”为需要的样子。

如果构造函数内部有return语句,而且return后面跟着一个对象,new命令会返回return语句指定的对象;否则,就会不管return语句,返回this对象。

var Vehicle = function () {
  this.price = 1000;
  return 1000;
};

(new Vehicle()) === 1000
// false

上面代码中,构造函数Vehicle的return语句返回一个数值。这时,new命令就会忽略这个return语句,返回“构造”后的this对象。

如果return语句返回的是一个跟this无关的新对象,new命令会返回这个新对象,而不是this对象

var Vehicle = function (){
  this.price = 1000;
  return { price: 2000 };
};

(new Vehicle()).price
// 2000

如果对普通函数(内部没有this关键字的函数)使用new命令,则会返回一个空对象。

function getMessage() {
  return "this is a message";
}

var msg = new getMessage();

msg // {}
typeof msg // "object"

函数内部可以使用new.target属性。如果当前函数是new命令调用,new.target指向当前函数,否则为undefined。

function f() {
  console.log(new.target === f);
}

f() // false
new f() // true

可以判断函数调用的时候,是否使用new命令。

function f() {
  if (!new.target) {
    throw new Error("请使用 new 命令调用!");
  }
  // ...
}

f() // Uncaught Error: 请使用 new 命令调用!
Object.create() 创建实例对象

有时拿不到构造函数,只能拿到一个现有的对象。我们希望以这个现有的对象作为模板,生成新的实例对象

var person1 = {
  name: "张三",
  age: 38,
  greeting: function() {
    console.log("Hi! I"m " + this.name + ".");
  }
};

var person2 = Object.create(person1);

person2.name // 张三
person2.greeting() // Hi! I"m 张三.

Object.getPrototypeOf()

方法返回参数对象的原型。这是获取原型对象的标准方法。

var F = function () {};
var f = new F();
Object.getPrototypeOf(f) === F.prototype // true

// 空对象的原型是 Object.prototype
Object.getPrototypeOf({}) === Object.prototype // true

// Object.prototype 的原型是 null
Object.getPrototypeOf(Object.prototype) === null // true

// 函数的原型是 Function.prototype
function f() {}
Object.getPrototypeOf(f) === Function.prototype // true

object.create方法,用来满足这种需求。该方法接受一个对象作为参数,然后以它为原型,返回一个实例对象。该实例完全继承原型对象的属性。

// 原型对象
var A = {
  print: function () {
    console.log("hello");
  }
};

// 实例对象
var B = Object.create(A);

Object.getPrototypeOf(B) === A // true
B.print() // hello
B.print === A.print // true
//以A对象为原型,生成了B对象。B继承了A的所有属性和方法。

三种方式生成的新对象是等价的。

var obj1 = Object.create({});
var obj2 = Object.create(Object.prototype);
var obj3 = new Object();

如果想要生成一个不继承任何属性(比如没有toString和valueOf方法)的对象,可以将Object.create的参数设为null

对象obj的原型是null,它就不具备一些定义在Object.prototype对象上面的属性,比如valueOf方法。

var obj = Object.create(null);

obj.valueOf()
// TypeError: Object [object Object] has no method "valueOf"

第二个参数:是一个属性描述对象,它所描述的对象属性,会添加到实例对象,作为该对象自身的属性。

实例对象的isPrototypeOf方法,用来判断该对象是否为参数对象的原型。

Object.prototype.isPrototypeOf({}) // true
Object.prototype.isPrototypeOf([]) // true
Object.prototype.isPrototypeOf(/xyz/) // true
Object.prototype.isPrototypeOf(Object.create(null)) // false

由于Object.prototype处于原型链的最顶端,所以对各种实例都返回true,只有直接继承自null的对象除外。

对象实例的hasOwnProperty方法返回一个布尔值,用于判断某个属性定义在对象自身,还是定义在原型链上。

Date.hasOwnProperty("length") // true
Date.hasOwnProperty("toString") // false
对象的拷贝

确保拷贝后的对象,与原对象具有同样的原型。
确保拷贝后的对象,与原对象具有同样的实例属性。

function copyObject(orig) {
  return Object.create(
    Object.getPrototypeOf(orig),
    Object.getOwnPropertyDescriptors(orig)
  );
}
//利用 ES2017 才引入标准的Object.getOwnPropertyDescriptors方法

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/94900.html

相关文章

  • NodeJs+Express+Mysql + Vuejs 项目实战 - 大纲

    摘要:多一个技能多一条出路,祝你在自学道路上越走越好,掌握自己的核心技能,不只是优秀,还要成为不可替代的人 NodeJs+Express+Mysql + Vuejs 项目实战 最近准备写一系列文章,全面讲述如何基于NodeJs + Express + Mysql + Vuejs 从零开发前后端完全分离项目; 文笔及技术可能在某些方面欠佳,请您指正,共同学习进步 前端:Vuejs全家桶 后端:...

    noONE 评论0 收藏0
  • jsliang 的 2019 面试准备

    Create by jsliang on 2019-2-11 15:30:34 Recently revised in 2019-3-17 21:30:36 Hello 小伙伴们,如果觉得本文还不错,记得给个 star , 小伙伴们的 star 是我持续更新的动力!GitHub 地址 并不是只有特定的季节才能跑路,只因为人跑得多了,这条路就定下来了。 金三银四跳槽季,jsliang 于 2019...

    PascalXie 评论0 收藏0
  • 从 1 到完美,用 node 写一个命令行工具

    摘要:从到完美,用写一个命令行工具中的字段现在,不管是前端项目还是项目,一般都会用做包管理工具,而是其相关的配置信息。又一个让命令行与用户进行交互的工具与功能差不多。比较常用的命令行命令行相关的应用就很多啦,比如等,但这些不仅仅是命令行工具。 从 1 到完美,用 node 写一个命令行工具 1. package.json 中的 bin 字段 现在,不管是前端项目还是 node 项目,一般都会...

    YorkChen 评论0 收藏0
  • Vultr机房测评 - Vultr美国达拉斯Dallas机房综合速度和线路去程回程测

    摘要:关于云服务器相关的文章优惠码优惠码整理专题每月更新最新优惠活动新用户最高送美元韩国机房机房测评韩国首尔机房综合速度和线路去程回程测试新人教程新人系列教程新注册账户且用优惠码享受赠送余额这篇文章中将会是Vultr十多个机房中的最后一个机房的测评。老蒋本来以为已经全部测评完毕,但是数数看居然少了一个,于是在这篇文章中补充下来自美国芝加哥机房的机房性能。实际上,我们通过前面的多篇文章测试的7个美国...

    CNZPH 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<