JS基础知识(二)原型和原型链

原型和原型链

问题:

  1. 如何准确判断一个变量是数组类型

  2. 写一个原型链继承的例子

  3. 描述new 一个对象的过程

  4. Zepto(或其他框架)源码中如何使用原型链

     

知识点: 

1.构造函数

function Foo (name, age) {
	this.name = name;
	this.age = age;
	this.class = 'class-1';
}


Foo
/* ƒ Foo (name, age) {
	this.name = name;
	this.age = age;
	this.class = 'class-1';
} */
var f = new Foo('xiaoming', 12)

f
//Foo {name: "xiaoming", age: 12, class: "class-1"}

 建议构造函数的首字母用大写便于阅读。

构造函数会默认return this.

这里讲一下“var f = new Foo('xiaoming', 12)”也就是new一个对象的过程:

首先先传入相应的参数在这个构造函数,然后其实先有一个this,为空对象,再将其进行赋值。像我们前一次讲到的对象是属于引用类型,引用类型可以无限的扩展属性,这里this.name,this.age都可以有点像那个无限扩展属性,给他加上属性,然后赋值,然后最后再返回一个return this。再将这个this传回来,赋值给f.

2.构造函数--扩展

语法糖:

语法糖就是一种便捷写法。在达到相同的目的情况下,更简便的方法。

  1. var a ={} 其实是var a = new Object() 的语法糖
  2. var a = [] 其实是var a = new Array()的语法糖
  3. function Foo(){...} 其实是var Foo =new Function(..)
  4. 使用instanceof 判断一个函数是否是一个变量的构造函数
     

对于一个变量的所有东西都有构造函数,对象,函数,数组都是有构造函数的.

对于1,2,3都推荐前者,易读且性能更好

//构造函数拓展
var a = {}

var b = []

function fn (){}

var a = new Object

var b = new Array

fn = new Function (...)

3.原型规则和示例

5条原型规则

原型规则是学习原型链的基础
(1)所有的引用类型(数组,对象,函数),都可以可自由扩展属性(除了null除外)

(2)所有的引用类型(数组,对象,函数),都有一个_proto_属性(简称他隐式原型),属性值是一个普通的对象。

(3)所有的函数,都有一个prototype(显式原型)属性,属性值也是一个普通的对象

(4)所有的引用类型(数组,对象,函数),_proto_属性值指向它的构造函数”prototype ”的属性值

(5) 当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的_proto_(即它的构造函数的prototype)中寻找。

var obj = {}

obj.a = 100

obj.b = 'abc'

obj
//{a: 100, b: "abc"}

var arr = [1,2,3]

arr.a = 100

arr
//(3) [1, 2, 3, a: 100]

function fn () {}

fn.a = 100

fn.b =200
obj
//{a: 100, b: "abc"}
arr
//(3) [1, 2, 3, a: 100]
fn
//ƒ fn () {}
obj.__proto__
//{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
arr.__proto__
//[constructor: ƒ, concat: ƒ, find: ƒ, findIndex: ƒ, pop: ƒ, …]
fn.__proto__
//ƒ () { [native code] }
fn
//ƒ fn () {}
Object
//ƒ Object() { [native code] }
fn.prototype
//{constructor: ƒ}
Object.prototype
//{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
obj
//{a: 100, b: "abc"}
obj.__proto__
//{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
Object
//ƒ Object() { [native code] }
Object.prototype
//{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
obj.__proto__ === Object.prototype
//true

4.原型链

 以一个例子来具体来看:

f是 通过构造函数Foo new的一个对象,他有一个自己的方法printName。同时构造函数还增加了一个方法的alertName。

Foo像一个类,而f是他类别下面一个具体的实例。

类的方法他都有,实例还有自己单独的方法。

function Foo(name,age){
	this.name = name;
}


Foo.prototype.alertName= function(){
	alert(this.name)
}

var f = new Foo('dd',13)

f.printName = function () {
	console.log(this.name)
}

f
//Foo {name: "dd", printName: ƒ}
f.printName()
//dd
f.alertName()

f.toString()
//"[object Object]"

f
//Foo {name: "dd", printName: ƒ}
f.__proto__
//{alertName: ƒ, constructor: ƒ}
Object
//ƒ Object() { [native code] }
Object.prototype
//{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
f.__proto__.__proto__
/*{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
constructor: ƒ Object()
hasOwnProperty: ƒ hasOwnProperty()
isPrototypeOf: ƒ isPrototypeOf()
propertyIsEnumerable: ƒ propertyIsEnumerable()
toLocaleString: ƒ toLocaleString()
toString: ƒ toString()
valueOf: ƒ valueOf()
__defineGetter__: ƒ __defineGetter__()
__defineSetter__: ƒ __defineSetter__()
__lookupGetter__: ƒ __lookupGetter__()
__lookupSetter__: ƒ __lookupSetter__()
get __proto__: ƒ __proto__()
set __proto__: ƒ __proto__()*/

 

其中含有一个this,this要看具体的情形来判断的,当比如说f.name这个this就是指向f. 

5.instanceof

用于判断引用类型属于哪个构造函数的方法

var arr = [1,2,3]

arr instanceof Array
//true
typeof arr
//"object"

问题解决:

  1. 如何准确判断一个变量是数组类型

    instanceof

  2. 写一个原型链继承的例子
     

    function Elem(id){
    	this.ele = document.getElementById(id);
    }
    
    Elem.prototype.html = function (value) {
    	var ele = this.ele;
    	if (value) {
    		ele.innerHTML = value;
    		return this;
    	}else {
    		return ele.innerHTML
    	}
    }
    
    Elem.prototype.on = function (type,fn) {
    	var ele = this.ele;
    	ele.addEventListener(type,fn);
    }
    
    
    var a = new Elem('article');
    a.on('click',function() {
    	alert('hello');
    });
    console.log(a.html());

    这里的return this可以使得在后面调用时候,进行循环调用。

  3. 描述new 一个对象的过程
    先传入相应的参数,也可以不传,然后在构造函数里面有一个this的空对象,对他进行扩展属性赋值,再返回一个this。将他返回给那个对象。

  4. Zepto(或其他框架)源码中如何使用原型链
    可以自行去查找相关资料看一下。

猜你喜欢

转载自blog.csdn.net/qq_37021554/article/details/84034313