构造函数

function Stu(name,age){
this.name=name;
this.age=age;
}
instanceof 查看引用类型对象是属于哪个构造函数的方法,通过__proto__ 一直往上找prototype,直到找到Object

原型规则和示例

所有的引用类型(数组/对象/函数)都可有扩展属性,都有一个隐式原型__proto__属性,所有函数都可以扩展prototype显示原型属性,属性值是个普通的对象,
所有的引用类型试图得到一个它本身的某个属性,会通过它的隐式原型__proto__去找它构造函数中的prototype
// 不希望打印出原型的属性,只打印自身属性

for(let item of f){
if(f.hasOwnProperty(item)){
console.log(item)
}
}

  

原型链

let f =new Foo();
f.alertName= function(){
// 方法具体实现
}
f.toString() //toString方法在Foo原型中找,找不到接着要去 f.__proto__.__proto__中查找

New一个对象的过程

  • 创建一个新的对象
  • this指向这个新的对象
  • 执行代码,即对this赋值
  • 返回this

原型链继承

function Elem(id){
  this.elem =document.getElementById(id);
}
Elem.prototype.html =function(val){
  if(val){
    return this.elem.innerHTML;
  }
  this.elem.innerHTML= val;
  return this; //将Elem对象返回
}
Elem.prototype.on =function(type,func){
  this.elem.addEventListener(type,func);
  return this;
}
const elem =new Elem('div1');
elem.html('张三').on('click',function(){
console.log('点击了文本,打印张三');
}).html(‘李四’)

实际应用

新建js文件my-z.js,如下是my-z.js文件源码,解释: slice.call能将具有length属性的对象转成数组 document.querySelectorAll(selector) 是个类数组, 没有.slice 原型,所以需要call,

… 或者[].slice.call(arguments, 0)
(function(window){

    var Z = function(dom,selector) {
var i,len =dom? dom.length: 0;
for(i=0;i<dom.length;i++){
this[i] =dom[i];
}
this.length =len;
this.selector =selector || ''
} var zepto = {}
zepto.Z= function(dom,selector){
return new Z(dom,selector)
}
zepto.init =function(selector){
var slice = Array.prototype.slice;
var dom =slice.call(document.querySelectorAll(selector)) //slice.call能将具有length属性的对象转成数组 document.querySelectorAll(selector) 是个类数组, 没有.slice 原型,所以需要call
return zepto.Z(dom,selector);
}
var $=function(selector){
return zepto.init(selector)
}
$.fn = {
css : function(key,value) {
alert(key+':'+value);
return this;
},
html : function() {
return this[0].innerHTML;
}
}
Z.prototype = $.fn;
window.$=$;
})(window);

  在index.html 引用该文件

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>prototype</title>
<body>
<div id="div1">div</div>
<p>title1</p>
<p>title2</p>
<p>title3</p>
<p>title4</p>
<!--<script type="application/javascript" src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>-->
<script type="application/javascript" src="my-z.js"></script>
</head>
<script type="application/javascript">
$('#div1').css('font-size','25px').css('color','#1ecc24') //链式调用
alert($('#div1').html())
</script>
</body>
</html>

JS插件扩展

为什么要把原型方法放在$.fn?

  1. 只有$会暴露在window 全局变量,暴露多个变量容易造成变量的污染
  2. 将插件扩展到$.fn.xxx这个web api 中,方便使用

示例如下所示:

$.fn.extend = function() {
var options, name, src, copy, copyIsArray, clone,
target = arguments[0] || {},
i = 1,
length = arguments.length,
deep = false;
if ( typeof target === "boolean" ) {
deep = target;
target = arguments[1] || {};
i = 2;
}
if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
target = {};
}
if ( length === i ) {
target = this;
--i;
}
for ( ; i < length; i++ ) {
if ( (options = arguments[ i ]) != null ) {
for ( name in options ) {
src = target[ name ];
copy = options[ name ];
if ( target === copy ) {
continue;
}
// 当用户想要深度操作时,递归合并
// copy是纯对象或者是数组
if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
// 如果是数组
if ( copyIsArray ) {
// 将copyIsArray重新设置为false,为下次遍历做准备。
copyIsArray = false;
// 判断被扩展的对象中src是不是数组
clone = src && jQuery.isArray(src) ? src : [];
} else {
// 判断被扩展的对象中src是不是纯对象
clone = src && jQuery.isPlainObject(src) ? src : {};
} // 递归调用extend方法,继续进行深度遍历
target[ name ] = jQuery.extend( deep, clone, copy ); // 如果不需要深度复制,则直接把copy(第i个被扩展对象中被遍历的那个键的值)
} else if ( copy !== undefined ) {
target[ name ] = copy;
}
}
}
}
// 原对象被改变,因此如果不想改变原对象,target可传入{}
return target;
};
$.fn.highlight = function (options) {
// 合并默认值和用户设定值:
var opts = $.fn.extend({}, $.fn.highlight.defaults, options);
this.css('backgroundColor', opts.backgroundColor).css('color', opts.color);
return this;
} // 设定默认值:
$.fn.highlight.defaults = {
color: '#d8d030',
backgroundColor: '#ecfdde'
}

验证插件效果:

<script type="application/javascript">
//验证插件扩展
$('#div1').highlight({
color: '#fff',
backgroundColor: '#333'
})
</script>

  

 

最新文章

  1. 19:A*B问题
  2. Saas
  3. C#Winform获取屏幕大小
  4. python模块概况,json/pickle,time/datetime,logging
  5. Angularjs总结(八)$ cookie和$rootscope
  6. Sicily1153-马的周游问题:启发式搜索
  7. 关于ROW_NUMBER函数的使用(The use of ROW_NUMBER function )
  8. assert()函数用法
  9. [PHP] PHP与Apache的模块配合说明
  10. Python中星号的本质和使用方式
  11. JavaScript中的日期时间函数
  12. #WEB安全基础 : HTTP协议 | 0x0 TCP/IP四层结构
  13. ReportMachine OCX 的使用方法
  14. react封装组织架构递归树
  15. 有符号无符号bit转换
  16. RS485接口为什么要接地
  17. 【前端学习笔记】call、apply、bind方法
  18. Linux下的ASLR(PIE)内存保护机制
  19. django--个人主页建立练习
  20. phpmyadmin-错误:配置文件权限错误,不应任何用户都能修改!这里有答案

热门文章

  1. (转)Memcached用法--参数和命令详解
  2. Kudu版本升级(官网推荐的步骤)(Upgrade from a Previous Version of Kudu)
  3. 关于java中char占几个字节,汉字占几个字节
  4. 【PHP】 hash加密
  5. POJ 3020——Antenna Placement——————【 最小路径覆盖、奇偶性建图】
  6. IOS如何打越狱包xcode无证书打包ios应用
  7. 多路复用select poll epoll
  8. Azure进阶攻略 | 数据库上云:零停机、自动化
  9. 用SQL将数字转换为中文数字
  10. 基于FPGA的VGA显示设计(二)