惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

小众软件
小众软件
A
About on SuperTechFans
博客园 - Franky
Engineering at Meta
Engineering at Meta
Recent Announcements
Recent Announcements
云风的 BLOG
云风的 BLOG
B
Blog
Microsoft Security Blog
Microsoft Security Blog
L
LangChain Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
U
Unit 42
Martin Fowler
Martin Fowler
Y
Y Combinator Blog
Stack Overflow Blog
Stack Overflow Blog
博客园 - 叶小钗
Vercel News
Vercel News
Apple Machine Learning Research
Apple Machine Learning Research
The Cloudflare Blog
Last Week in AI
Last Week in AI
腾讯CDC
Microsoft Azure Blog
Microsoft Azure Blog
爱范儿
爱范儿
V
V2EX
G
Google Developers Blog

博客园 - 大老鼠

JQuery ajax 传递数组 自定义属性 JQuery元素坐标,偏移量 IE8按F12不显示开发人员工具窗口 JQuery AJAX调用WEB SERVICE方法 JQuery Validate验证表单元素 - 大老鼠 - 博客园 序列化/反序列化JSON sqlserver使用select加锁 jQuery操作解析JSON (sp_dbcmptlevel)将某些数据库行为设置为与指定的 SQL Server 版本兼容。 jQuery使用手册 效果-为操作添加艺术性 DOM操作-基于命令改变页面 事件 选择符-取得你想要的一切 jQuery入门 动态修改样式和层叠样式表 - 大老鼠 - 博客园 DOM2核心和DOM2 HTML JavaScript中常见陷阱 - 大老鼠 - 博客园
创建可重用的对象
大老鼠 · 2010-04-26 · via 博客园 - 大老鼠

对象中包含什么:

JavaScript中的大多数对象可以分为如下两种类型:

Function对象,例如alert()函数,可以使用参数来改变这类对象的功能。

Object对象,这类对象不能像函数那样被调用,而且具有固定的功能-除非它们包含额外的Function对象 

为了提高效率,JavaScript也提供了下列内置对象:

1、Object是通用基础对象,可以使用它来创建简单的静态对象  

2、Function是被所有使用参数的对象复制的对象,也是在脚本中定义函数时所创建的对象  

3、Array是一种特殊的属性和方法的集合,比如使用其length属性可以通过循环迭代操纵这类对象也可以使用方括号  

4、String、Boolean和Number则分别用于表示字符串、布尔值以及数字所有内置对象都可以通过new关键字或者其它特殊语法来创建,花括号({})是Object的简写形式,而方括号(【】)则是Array的简写形式。 

 Window对象中的一切
  function myFunction(message){
    alert(message);
  }
  如果上面的函数是在JavaScript文件最顶层编写的没有被其它对象包含的代码,那么:
  myFunction('without window ojbect');
  window.myFunction('with window object');
  这两种调用方法结果是相同的,但是如果是在另一个对象中创建的这个函数,由于作用域链的关系,情况会变得复杂一些
 
function override(){
  //覆盖alert函数
  var alert = function(message){
    window.alert('overridden:' + message);
  }
  alert('alert');

  //在override()函数的作用域中调用原始的alert()函数
  window.alert('window.alert');
}

//在window的作用域中调用原始的alert()函数
alert('alert from outside');
 
在页面载入完成后,会有三个警告提示:"overridden:alert"、"window.alert"、"alert from outside",当然,如果在脚本文件最顶层如下写:
var alert = function(message){

  window.alert('overridden:' + message);
}
alert('test');
那么脚本会因为过渡递归而终止运行。因为这次是在脚本的最顶层覆盖的alert()方法,相当于你自己的方法替换了window.alert()方法。

创建你自己的对象
//创建构造函数
function myConstructor(message){
  alert(message);
  this.myMessage = message;
 
  //私有属性
  var separator = '-';
  var myOwner = this;

  //私有方法
  function alertMessage() {
    alert(myOwner.myMessage);
  }
  //在实例化时显示信息
  alertMessage();

  //特权方法(也是公有方法)
  this.appendToMessage = function(string){
    this.myMessage = separator + string;  //特权方法内可以访问私有成员separator
    alertMessage();
   }
}

//静态属性
myConstructor.name = 'Jeff';

//静态方法
myConstructor.alertName = function(){
  alert(this.name);
}


//添加一个公有方法
myConstructor.prototype.clearMessage = function(string){
  this.myMessage += ' ' + string;

  //这是错误的
  this.myMessage += separator + string;
}

在新实例上调用clearMessage将得到预期的效果
var myObject = new myConstructor('hello world');
myObject.clearMessage();
myObject.appendToMessage();    //特权方法也是公有方法

你可能已经注意到了,这个例子代码中也包含另外一个私有属性myOwner,它引用的是this。通过将this赋值给myOwner,你的私有方法就可以通过引用myOwner来访问myConstructor的实例。私有方法是存在于构造函数作用域中的自包含对象,它们实际上并不是prototype的方法,因此在私有方法内部this引用的只是私有方法的实例,而非myConstructor的实例。由于这些私有成员被严格限制在了构造函数的作用域中,因此也不能通过对象自己的公有方法来访问它们。要避免这一限制,可以使用特权方法 
对象字面量
var myObject = {
  propertyA: 'value',
  propertyB: 'value',
  methodA:function(){},
  methodB:function(){}
}
上面的代码跟下面的代码是等效的:
var myObject = new object();
myObject.propertyA = 'value';
myObject.proertyB = 'value';
myObject.methodA = function(){};
myObject.methodB = function(){};
也是就是,下面的简写形式是等效的:
var myObject = {}; var myObject = new object();

也可以使用对象字面量语法向prototype属性中添加所有仅有成员
myConstructor.prototype = {
  propertyA:'value',
  propertyB: 'value',
  methodA:function(){},
  methodB:function(){}  
}

通过Call()和apply()重新定义执行环境
function doubleCheck(){
  this.message = 'are you sure you want to leave?';
}
doubleCheck.prototype.sayGoodby = function() {
  return confirm(this.message);  
}
 
function initPage(){
  var clickedLink = new doubleCheck();
  var links = document.getElementsBytagName('a');
  for(var i = 0; i < links.length; i++){
    links.attachEvent("onclick",clickedLink.sayGoodby);
  }
}
window.attachEvent("onload",initPage);

这个例子中载入事件的预期效果是遍历页面中的所有链接,然后clickedLink.sayBoodby执行链接的click事件。但是由于this引用的对象会随着环境而改变,当例子中的sayGoodby()方法在<a>这个HTML元素的环境中执行时,this所引用的就是这个HTML元素,而不是你所期望的clickedLink对象,解决这个问题的方法就是使用Function对象的call()或apply()方法,用以改变函数的执行环境
clickedLink.sayGoodby.call(window)或者clickedLink.sayGoodby.apply(window);

如果sayGoodby带有参数可以使用下面方法:
clickedLink.sayGoodby.call(window,argument1,argument2,...);
clickedLink.sayGoodby.apply(window,arguments);
对于apply,应该将方法的参数做为数组放在第二个参数位置传递,这是它们的唯一区别

function bindFunction(obj,func){
  return function(){
    func.apply(obj,arguments);
  }
}
以上代码的关键在于,由bindFunction返回的匿名函数使用内部作用域中特殊的arguments参数,作为以外部作用域中的obj和func调用apply()时传递的额外参数,执行以上方法主要是为了给原始函数创建一个新环境。