原型链:
每创建出来一个构造函数,就会绑定一个神秘而且强大的对象
这个对象就是原型
原型是一个对象 既然是对象 就有对应的构造函数
那么构造函数肯定也有自己的原型
原型本身是一个对象
对象又会有构造函数 构造函数又会有 对应的原型
这样就形成了一个链式结构
这个链式结构就是原型链
最上层的object的原型的原型是null
原型链作用:
原型链上面所有的属性跟方法 后面的对象都可以调用
自定义构造函数 在没有原型替换的基础上默认的原型链是:
当前对象 -> 构造函数.prototype -> Object.prototype -> null
function Person() {
}
var per=new Person();
console.log(per);// 当前对象
console.log( per.__proto__);//构造函数.prototype
console.log(per.__proto__.__proto__);//Object.prototype
console.log(per.__proto__.__proto__.__proto__);//null
利用原型实现内置对象功能扩展
继承!!!! 原型替换继承
function MyArray() {
}
// 继承!!!! 原型替换继承
MyArray.prototype=new Array();
MyArray.prototype.sort=function () {
console.log("就不排序,气死你");
}
var arr=new MyArray();
arr.sort();
var arr1=[8,4,2,3,5];
arr1.sort(function (a,b) {
return b-a;
})
console.log(arr1);
自己构建原型链
要想自己构建自定义的原型链结构 那么就要用到原型替换
属性或者方法的调用原则:
首先在当前构造函数中寻找
如果有直接调用
如果没有则继续去原型里面找
原型里面有直接调用
如果没有则去原型链上面找
找到就调用
一直到原型链的最上层都没有
则属性返回undefined
方法报错!
<script>
function F1() {
this.show=function f() {
console.log("我是f1的show!")
}
this.eat=function () {
console.log("F1的eat")
}
}
F2.prototype=new F1();
F2.prototype.constructor=F2;
function F2() {
this.show=function () {
console.log("我是f2的show!")
}
this.look=function () {
console.log("我是F2的look")
}
}
F3.prototype=new F2();
F3.prototype.constructor=F3;
function F3() {
this.show=function () {
console.log("我是f3的show!")
}
}
var per=new F3();
per.show();
per.look();
per.eat();
console.log(per.__proto__);//F2
console.log(per.__proto__.__proto__);//F1
console.log(per.__proto__.__proto__.__proto__);//F1的原型 obj
console.log(per.__proto__.__proto__.__proto__.__proto__);//obj的原型
console.log(per.__proto__.__proto__.__proto__.__proto__.__proto__);//null
</script>
Object.prototype常用的方法
Object.prototype.__proto__
对象.__proto__
指向当对象被实例化的时候,用作原型的对象。
Object.prototype.hasOwnProperty()
对象.hasOwnProperty()
返回一个布尔值 ,表示某个对象是否含有指定的属性,而且此属性非原型链继承的。
Object.prototype.isPrototypeOf()
返回一个布尔值,表示指定的对象是否在本对象的原型链中。
Object.prototype.toString()
返回对象的字符串表示。
Object.prototype.valueOf()
返回指定对象的原始值。
Function创建构造函数
之前的创建函数的方式:
1. 变量模式创建(匿名函数)
var 函数名=function(){}
2.函数模式创建
function 函数名(){
}
之前创建出来的函数 本身也是一个对象
既然是对象 就有自己对应的构造函数
函数对象对应的构造函数就是 Function
所以系统一定有一个: function Function(){}
所以第三种创建函数的方式:
var func=new Function();
通过Function创建一个函数
var 函数名 =new Function(函数的形参1,函数的形参2,...函数的形参n,字符串函数体代码)
只要保证最后一个参数是函数体代码的字符串格式就行
前边所有的参数都是定义该函数的形参
var plus=new Function("a","b","return a+b;");
/*
相当于
function plus(a,b){
return a+b;
}
*/
console.log(plus(5, 7));
用Function方式创建一个构造函数
var Person=new Function("name","age","this.name=name;this.age=age;");
var per=new Person("小砌墙",16);
console.log(per);
Function创建函数参数代码过长问题
四种方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="template" style="display: none">
var max=a;
if(b>max){
max=b;
}
if(c>max){
max=c;
}
return max;
</div>
<!--type只要随便写个东西就行 只要不是text/javaScript就行
推荐写 text/template
-->
<script id="sc" type="text/template">
var max=a;
if(b>max){
max=b;
}
if(c>max){
max=c;
}
return max;
</script>
<script>
/*
function getMax(a,b,c) {
var max=a;
if(b>max){
max=b;
}
if(c>max){
max=c;
}
return max;
}
由于Function方式创建的函数 代码过长 所以有以下这么几种解决方式:
第一种:字符串换行 +
var getMax=new Function("a","b","c","var max=a;" +
"if(b>max){" +
"max=b;" +
"}" +
"if(c>max){" +
"max=c;" +
"}" +
"return max;")
第二种: 模板字符串(es6)
var getMax=new Function("a","b","c",`
var max=a;
if(b>max){
max=b;
}
if(c>max){
max=c;
}
return max;
`)
第三种方式: 利用页面标签定义模板
var getMax=new Function("a","b","c",document.getElementById("template").innerText)
第四种方式: 利用 页面的script标签写模板
注意script标签的type改成其他的
*/
var getMax=new Function("a","b","c",document.getElementById("sc").innerText)
console.log(getMax(56, 78, 129));
</script>
</body>
</html>