流年似水博客开通了,本站主要是写关于Web和大数据方面内容,正在更新中,欢迎大家光临!
  1. 文章:97 篇
  2. 总浏览:69,700 次
  3. 评论:22条
  4. 最后更新:2020-06-08
  5. 分类目录:39 个

JS 原型与原型链

Javascript l, xy 363℃ 0评论

一、普通函数于函数对象

javascript中万物皆对象!但对象也有区分,分为普通对象、函数对象,Object、Function是JS自带的函数对象。下面举例说明:

//列一下哪些是对象
var o1 = {};
var o2 = new Object();
var o3 = new f2();

var f1 = function() {}
function f2() {}
var f3 = new Function("str", "return str")

console.log(typeof Function)//function
console.log(typeof Object )//function

console.log(typeof f1 )//function
console.log(typeof f2)//function
console.log(typeof f3)//function

console.log(typeof o1)//object
console.log(typeof o2)//object
console.log(typeof o3)//object

上面例子中o1,o2,o3都是普通对象,f1,f2,f3都是函数对象,函数对象都是new Function()创建的,这里你可能会说,f1,f2不是,那你就大错特错了,这种创建方式只是new Function的一种语法糖,它的创建还是一样的。

二、构造函数

1、介绍constructor(构造函数)

构造函数和普通函数的创建方法是一样的

构造函数和普通函数的不同之处在于调用方式不同,作用也不同(构造函数用来创造事例)

2、 构造函数的运行过程:

  • 立刻在堆内存中生成一个对象
  • 这个新建对象设置为当前函数中的this
  • 逐个执行函数中的代码
  • 将新建的对象作为返回值

3、实例

function Person(name, age) {
       this.name = name;
       this.age = age;
       this.sayName = function() {
       console.log(name)
       };
   }
var p1 = new Person("xy", 12)
var p2 = new Person("jiangjiang", 22)
console.log(p1.constructor == p2.constructor); //true
console.log(p1.constructor == Person); //true
console.log(p2.constructor == Person); //true

4、总结:

p1和p2都是构造函数Person的实例,都有一个constructor(属性)指向Person。

一个公式:

实例的构造函数属性(constructor)指向构造函数。

三、prototype (对象原型)

在 JavaScript 中,每当定义一个对象(函数也是对象)时候,对象中都会包含一些预定义的属性。其中每个函数对象都有一个prototype 属性,这个属性指向函数的原型对象

function Person() {}
Person.prototype.name = "xueyan";
Person.prototype.age = 24;
Person.prototype.sayName = function() {
    console.log(this.name);
}
var p1 = new Person();
var p2 = new Person();
console.log(p1.sayName == p2.sayName); //true

在这里我们要明确,每个对象都有__proto__属性,但只有函数对象才有prototype属性

那么什么是对象原型呢,我们把上面例子来修改一下,你就会明白

function Person() {}
Person.prototype = {
    name : "xueyan",
    age : 24,
    sayName :  function() {
            console.log(this.name);
        }
}
 var p1 = new Person();

这两种写法是一样的,原型对象其实就是个普通的对象,这里的原型对象就是Person.prototype.


我们再结合上一节中的constructor(构造函数)来看下,它跟原型对象有啥联系呢

上面例子中的Person.prototype赋值了name age sayName 的同时还又一个默认的属性constructor,根据上一节所讲,constructor属性都会指向它所在的函数Person,即:

Person.prototype.constructor == Person

这里还有一个遗漏,有人肯定会问,p1,p2呢?啊,第二节我们说实例的构造函数属性(constructor)指向构造函数,p1和p2在这里的构造函数都是Person,所以我们得出结论:

p1.constructor == Person


这里我们顺便验证一下上面说的 “每个对象都有__proto__属性,但只有函数对象才有prototype属性” 

console.log(typeof p1) //Object
console.log(typeof Person) //Function
console.log(p1.prototype) //undefined
console.log(Person.prototype) //Person{}

这时p1.prototype是undefined,在看它的属性为Object,p1虽身为Person的实例,但它依旧改不了它是个普通对象的本质,固然,它没有prototype属性,约定俗成的是只有函数对象才有。

总结:

console.log(Person.prototype) //Person{}   
console.log(typeof Person.prototype) //Object
console.log(typeof Function.prototype) // Function,这个特殊
console.log(typeof Object.prototype) // Object

原型对象其实就是普通对象(但 Function.prototype 除外,它是函数对象,但它很特殊,他没有prototype属性(前面说道函数对象都有prototype属性))。所有的函数对象都是new Function生成。


四、__proto__(隐式对象)

JS 在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__ 的内置属性,用于指向创建它的构造函数的原型对象。

对象 person1 有一个 __proto__属性,创建它的构造函数是 Person,构造函数的原型对象是 Person.prototype ,所以:

p1.__proto__ == Person.prototype


《JavaScript 高级程序设计》的图 6-1


由上图可以看出:

Person.prototype.constructor == Person;
person1.__proto__ == Person.prototype;
person1.constructor == Person;

person1 就是我们的p1啦!

p1的关系我们了解清楚了,即:

function Person(){}
var p1 = new Person()
Person.prototype.constructor == Person;
p1.__proto__ == Person.prototype;
p1.constructor == Person;

关系图如下:

到这里我们就该忘深里再研究一下子了,Object、Function 跟我们这个Person是啥关系呢?

  • Person是个函数对象,var Person = new Function();

  • prototype(对象原型)虽然为默认属性,但是也是一个对象,即生成方式为:Person.prototype = new Object();  

  • Object 在第三节我们总结时,发现Object是个函数方法,即使函数方法,即生成方式为:var Object = new Function();

扩展图如下:

转载请注明:流年似水 » JS 原型与原型链

喜欢 (0)or分享 (0)

Warning: copy(https://cn.gravatar.com/avatar/?s=54&d=%2Fwp-content%2Fthemes%2Fyusi1.0%2Fimg%2Fdefault.png&r=g): failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request in /usr/share/nginx/html/timewentby/wp-content/themes/yusi1.0/functions.php on line 239

Warning: copy(/wp-content/themes/yusi1.0/img/default.png): failed to open stream: No such file or directory in /usr/share/nginx/html/timewentby/wp-content/themes/yusi1.0/functions.php on line 243
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址