js的对象与函数详解

一、对象

就是人们要研究的任何事物,不仅能表示具体事物,还能表示抽象的规则,计划或事件。
         属性的无序集合,每个属性可以存一个值(原始值,对象,函数)

对象的特性:封装,尽可能的隐藏对象的部分细节,使其受到保护。只保留有限的接口和外部发生联系。

js 中{},[] 来定义数组和对象

1.{ } 大括号,表示定义一个对象,大部分情况下要有成对的属性和值,或是函数。

2.[ ]中括号,表示一个数组,也可以理解为一个数组对象。

3.{ } 和[ ] 一起使用,我们前面说到,{ } 是一个对象,[ ] 是一个数组,我们可以组成一个对象数组

调用起来对象的属性用.(点)叠加/对象名['属性名称'],数组用 [下标] 来访问。

二、Js自定义对象的2种方式

1、对象初始化器构造对象

 var marry={
 name:"marry",
 age:2,
 shout:function(){
  alert("我是:"+this.name+",今年:"+this.age);
 },
 action:function(){
  alert("会吃");
 }
 };
 alert(marry.name);
 alert(marry.age);
 marry.shout();
 marry.action();

2.定义对象的内存分别

当我们创建一个对象 ren,会在栈内存中保存一个地址,栈为长度不可变的地址。

而栈中的地址就对应堆中的存储地址。堆中的存储地址,只要实例化会在堆中开辟一块空间,地址就是栈的地址,内容就是实例化对象里面的内容,如name,sex,eat。可以通过地址引用,访问里面的属性和方法。

当我们再实例化一个对象,又会保存另一个地址及开辟一块空间。

代码段,共同的属性或方法放在代码段中,不在堆中。只执行一次,节省内存空间。代码段会一直存在内存的空间中,知道浏览器关闭。使用prototype方法创建

var ren ={};
ren.name="张三";
ren.sex="男";
ren.eat=function () {
  alert("吃饭");
}
alert(ren.name);
alert(ren["name"]);

3.工厂模式

工厂模式虽然解决多次创建相似对象的重复性问题,但是并没有解决对象识别问题,也就是typeof之后他都显示object,具体的对象是什么并没有显示。

function createPerson(name,age,job)
  {
    var o=new Object();
    o.name=name;
    o.age=age;
    o.job=job;
    o.sayName=function(){
      alert(this.name);//this指的是o
    }
    return o;
  }
  var person1=createPerson("Tom",23,"厨师");
  person1.sayName();

4、构造函数方式

构造函数模式和工厂模式的区别

  1.没有显式的创建对象。

  2.将属性和方法赋给了this对象。

  3.没有return语句。

  4.函数名第一个字母大写。

  构造函数模式优于工厂模式的原因就是,构造函数模式中的对象实例(person1)通过constructor属性或instanceof操作符可以验证person1既是Object的实例,也是Person的实例,同时也证明所有对象均来自于Object。

function Person(name,age,job)
  {
    this.name=name;
    this.age=age;
    this.job=job;
    this.sayName=function(){
      alert(this.name);//this是Person
    }
  }
  var person1=new Person("Tom",23,"厨师");
  person1.sayName();
 function Dog(name,age){
 this.name=name;
 this.age=age;
 this.shout=function(){
  alert("我是:"+this.name+",今年:"+this.age);
 };
 this.action=function(){
  alert("会吃");
 };
 }
 var jack=new Dog("jack",1);
 alert(jack.name);
 alert(jack.age);
 jack.shout();
 jack.action();

5.全局作用域

但是构造函数也有缺点,对象是引用类型,对象实例化不是指针的改变,而是简单的复制,复制对象的方法和属性,假设一个对象有上千个实例,它就会复制上千个功能相同的方法,这显然是不可取的。

我们也可以把sayName()函数的定义战役到构造函数的外部,这样我们就将sayName属性设置成等于全局的sayName函数,这样实例化对象就共享全局作用域中的同一个sayName(),解决了构造函数对象方法的多次创建问题。但是全局作用域定义的sayName()函数只能被某个对象调用谈什么全局作用域,而且如果构造函数对象的方法有很多,就需要定义很多全局函数,封装性又从何谈起,于是原型模式应运而生。

 function Person(name,age,job)
  {
    this.name=name;
    this.age=age;
    this.job=job;
    this.sayName=sayName;
  }
  function sayName(){
    alert(this.name)
  }
  var person1=new Person("Tom",23,"厨师");
  person1.sayName();

6.构造函数创建对象

定义对象模拟数组,arguments为js内置的对象。

function myArray () {
var lengs= arguments.length;
for (var i=0; i<lengs; i++) {
this[i]=arguments[i];
}
}
var arr=new myArray(1,2,3);
alert(arr[0]);

7.js动态构造对象

<script type="text/javascript">
 /* function speak(something){
 alert(something);
 } */
 /* var p=new Object();
 p.name="Jack"; // 动态的添加属性
 p.func=speak; // 动态的添加方法
 alert(p.name);
 p.func("Hello,Hello,大家好!"); */
 /* delete p.name; //删除属性 输出undefine
 alert(p.name);
 delete p.func;
 p.func("Hello,Hello,大家好!"); */
 /* p.name=undefined;
 p.func=undefined;
 alert(p.name);
 p.func("Hello,Hello,大家好!"); */
 function person(name,age){//构造方法
 this.name2=name;//给当前对象动态添加属性
 this.age2=age;
 function speak(something){
  alert(something);
 }
 this.func=speak;
 }
 var p1=new person("Jack",12);
 alert(p1.name2);
 p1.func("Hello,EveryOne!");
</script>

三、原型模式创建对象

我们创建的每一个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,这个对象中包含着所有对象实例的属性和方法,这个对象就是原型对象。通俗的说,原型对象中的方法和属性可以被所有对象的实例所共享,对象实例就不用多次创建相同的方法和属性。

function Person(){
  };
  Person.prototype={
    name:"Tom",
    age:23,
    job:"web前端工程师",
    sayName:function(){
      alert(this.name);
    }
  }
  var person1=new Person();
  person1.sayName();

1.工厂函数封装,通过一个函数封装起来

function dianshi (color,size,brand) {
var Tv={};
Tv.color=color;
Tv.size=size;
Tv.brand=brand;
Tv.look=function () {
alert("看电视");
}
Tv.play=function () {
alert("玩游戏");
}
Tv.dvd=function () {
alert("DVD");
}
 return Tv;
}
var ds=dianshi("red","30inch","sony");
//alert(typeof ds)//返回object
alert(ds.color)
var ds1=dianshi("blue","40inch","changh");
alert(ds1["size"])//传递参数

2.构造函数

function Tv(color,size,brand) {
this.color=color;//那个对象引用this就代表那个对象
this.size=size;
this.brand=brand;
this.play=function () {
alert("玩游戏");
}
this.look=function () {
alert("看电视");
}
}
var sony=new Tv("red","20 inch","sony");
alert(sony.color)

3.prototype方法

共同的属性与方法放在代码段,节省内存空间

function Tv(color,size,brand) {
this.color=color;
this.size=size;
this.brand=brand;
this.play=function () {
alert("玩游戏");
}
}
Tv.prototype.look=function () {
 alert("看电视");
 }
Tv.prototype.dvd=function () {
 alert("DVD");
 }
Tv.prototype.aaa={name:"张三"};//只能共享属性或函数,不能共享对象
var sony=new Tv("red","20 inch","sony");
var changhong =new Tv("red","20 inch","CH");
 delete sony.color
 delete sony.play//undefine
 delete sony.look//能访问到
sony.look();
changhong.look();
sony.aaa.name="李四"//李四
changhong.aaa.name//李四
全局对象Array扩展增加removeByValue方法
Array.prototype.removeByValue = function(val) {
 for(var i=0; i<this.length; i++) {
  if(this[i] == val) {
   this.splice(i, 1);
   break;
  }
 }
}

虽然可以通过对象实例访问保存在原型对象中的值,但却不能通过对象实例重写原型的值。其实对象实例获取某一属性的值是从本身开始寻找,然后是原型对象,最后是构造函数对象,所以重写对象实例的属性值(这个值可以通过delete操作符删除)仅仅是阻断了获取原型属性值的途径,但是没有改变其中的值。

function Person(){
};
Person.prototype.name="Tom";
Person.prototype.age=23;
Person.prototype.job="厨师";
Person.prototype.sayName=function(){
  alert(this.name);
}
var person1=new Person();
var person2=new Person();
person1.name="Mike";
alert(person1.name);
alert(person2.name);
alert(person1.name);
alert(person2.name);

4.面向对象创建对象

用面向对象语法表示的时候,原型对象的constructor属性不在指向Person,因为每创建一个函数,同时会创建它的prototype对象,用面向对象语法本质上相当于重写了prototype对象,constructor属性也会变成新对象的constructor属性(这里指向Object)

 function Person(){
  };
  Person.prototype={
    constructor:Person,
    name:"Tom",
    age:23,
    job:"厨师",
    sayName:function(){
      alert(this.name);
    }
  }
  var person1=new Person();
  var person2=new Person();
  person1.name="Mike";
  alert(person1.name);
  alert(person2.name);

原型模式的缺点:因为所以对象实例共享原型对象的方法和属性,但是往往实例都有他自己私有的属性,这时候原型模式就不适用了,所以我们可以混合使用构造函数模式和原型模式。

5.混合方法

组合使用构造函数模式和原型模式结合了构造函数和原型模式的优点,构造函数定义实例的私有属性,原型模式定义共享属性和方法。

function Tv(color,size,brand) {
  this.color=color;
  this.size=size;
  this.brand=brand;
  this.play=function () {
   alert("玩游戏");
  }
 Tv.prototype.aaa={name:"张三"};
 }
  Tv.prototype.look=function () {
   alert("看电视");
  }
  Tv.prototype.dvd=function () {
   alert("DVD");
  }
}
 function Person(name,age,job){
    this.name=name;
    this.age=age;
    this.job=job;
  };
  Person.prototype={
    constructor:Person,
    sayName:function(){
      alert(this.name);
    }
  }
  var person1=new Person("Tom");
  var person2=new Person("Mike");
  alert(person1.name);
  alert(person2.name);

四、js对象属性

如果属性的值是函数,我们叫做他是对象的方法,否则叫做是属性。

1.私有属性,对象属性,类属性

<script type="text/javascript">
 function C(){
 this.objPro="对象属性";
 C.prototype.objPro2="对象属性2";//原型
 var privatePro="私有属性";//只能在方法内部使用
 }
 C.classPro="类属性";
 alert(C.classPro);
 var c=new C();
 alert(c.objPro);
 alert(c.objPro2);
</script>

2.私有方法,对象方法,类方法

<script type="text/javascript">
 function C(){
 var privateFunc=function(){
  alert("私有方法");
 };
 privateFunc();
 this.objFunc=function(){
  alert("对象方法");
 };
 C.prototype.objFunc2=function(){
  alert("对象方法2");
 };
 }
 C.classFunc=function(){
 alert("类方法");
 };
 C.classFunc();
 var c=new C();
 c.objFunc();
 c.objFunc2();
</script>

五、js函数

1. 函数的定义:

1.采用关键字function来定义

 function fun(){
   alert("大家好")
 }
 // fun() ;

2.采用匿名函数的方式(采用function作为名字)

var a = function(){
 alert("我是匿名函数") ;
}
// a() ;

3.采用new Function()的方式

小括号中最后一个参数是函数体,之前所有的参数都是形参.

 var b = new Function("x","y","z","alert(x+y+z)") ;
// b(3,4,5) ;

前面是参数,最后的是方法体

 var sayFunc=new Function("name","age","alert(name+'今年'+age+'岁了')");
 // sayFunc("李四",4);
 alert("sayFunc方法对象的方法参数个数:"+sayFunc.length);
 alert(sayFunc.toString());//获取源码
 alert(sayFunc.valueOf());//获取源码

2.调用函数:

调用函数的时候是用函数名来寻找的,函数名(参数)

初始化函数/自调函数

(function () {alert("函数调用");})();

3.函数劫持

函数劫持:改变javascript的预定义的函数预定义好的功能

window.alert = function(x){
  document.write(x) ;
}
  alert("abc") ;

4.函数表达式

  var fun = function(){
    alert('我是函数表达式的形式')
  }
  fun();//函数调用

注意:

1.如果两个函数的命名相同,后面的将会覆盖前面的函数。

2.以基本语法声明的函数,会在代码运行的时候,提前加载到内存当中,以供以后使用,但是匿名函数形式命名的函数,会在执行到的时候,才进行赋值

3.在不同的<script></script>块中的函数,使用和调用的时候,应该先定义,后执行。

4.函数参数arguments对象

每创建一个函数,该函数就会隐式创建一个arguments数组对象,他包含有实际传入参数的信息。

  • 1.length   检测实际传入参数的个数
  • 2.callee   对本身的调用

访问传入参数的具体的值:([下标])

 function fun (a,b) {
   for (var i=0; i<arguments.length; i++) {
   alert(arguments[i])
   }
  }

若有不足请多多指教!希望给您带来帮助!

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。如果你想了解更多相关内容请查看下面相关链接

(0)

相关推荐

  • vue.js的vue-cli脚手架中使用百度地图API的实例

    第一步,去百度地图开发者申请密钥. 1.申请密钥(百度地图开放平台-->开发文档-->web开发-->JavaScript  API-->立即使用-->创建应用) 2.密钥申请成功后 第二步,在项目的需要模板中引入,具体如下: 项目路径 其中index.html存放地图链接,代码如下 在百度地图开放平台 服务介绍中 选择我们所需要的地图类型  demo演示可查看 选择我们所需哪种百度地图的类型:http://lbsyun.baidu.com/index.php?title=j

  • js变量声明var使用与不使用的区别详解

    一.区分显示的声明与隐式声明(var) JS中变量声明分显式声明和隐式声明. var name = 'muzidigbig';//显示声明 name = 'muzidigbig';//隐式声明(为全局变量的一个属性) 在函数中使用var关键字进行显式声明的变量是做为局部变量,在全局范围内声明的变量为全局变量:而没有用var关键字,使用直接赋值方式声明的是全局变量(全局对象属性). // name = 'muzidigbig';//隐式声明(为全局变量的一个属性) console.log(name

  • 使用javascript做时间倒数读秒功能的实例

    某个试卷在线考试需要读秒.网上找了一会就是没找到我想要的.只好自己改改网上的,这也用用,那也用用. 其他代码不贴了.贴相关的: html页面代码: <a class="btn btn-default" onclick="StartExamine();">开始</a> <div id="TimeClock" class="col-md-4" ><span class="text

  • javascript json字符串到json对象转义问题

    在使用JavaScriptSerializer.Serialize 方法转json对象时,遇到一个问题,后台方法生成的json字符串中有没有转义的特殊字符代码: 而这些特殊的代码在使用javascript的转json对象方法时报错,为了讲这个转义的东西转义过来,折腾了半天.着实对javascript无语: 后台代转的对象是 Dictionary<string,string> DepartmentsExistTaskCounts 前台页面使用的MVC里的razor 写法,直接使用后台方法把数据转

  • js中对象和面向对象与Json介绍

    ECMA-262 把对象(object)定义为"属性的无序集合,每个属性存放一个原始值.对象或函数".严格来说,这意味着对象是无特定顺序的值的数组. 面向对象语言的要求 一种面向对象语言需要向开发者提供四种基本能力: 封装 - 把相关的信息(无论数据或方法)存储在对象中的能力 聚集 - 把一个对象存储在另一个对象内的能力 继承 - 由另一个类(或多个类)得来类的属性和方法的能力 多态 - 编写能以多种方法运行的函数或方法的能力 对象的创建和销毁都在 JavaScript 执行过程中发生

  • js序列化和反序列化的使用讲解

    (1)序列化 即js中的Object转化为字符串 1.使用obj.toJSONString() var str=obj.toJSONString(); //将JSON对象转化为JSON字符 2.使用JSON.stringify(obj) var str=JSON.stringify(obj); //将JSON对象转化为JSON字符 (2)反序列化 即js中JSON字符串转化为Object 1.使用eval('('+josnStr+')') var obj=eval("("+data+&

  • JS实现将对象转化为数组的方法分析

    本文实例讲述了JS实现将对象转化为数组的方法.分享给大家供大家参考,具体如下: 前言 其实这本来应该是一个很基础的问题了,但我之做一想记录一下是因为之前因为对象转数组的时候卡住了后来弄了出来,但最近再遇到这个问题时竟然又卡主了,所以,关于这个问题,如何把一个对象{'未完成':5, '已完成':8, '待确认':4, '已取消':6}转为[{"未完成":5},{"已完成":8},{"待确认":4},{"已取消":6}],你已经知

  • js中innerText/textContent和innerHTML与target和currentTarget的区别

    一.获取/赋值文本值innerText/textContent.innerHTML <body> <div id="box_text"> <p style="color:hotpink;">muzidigbig</p> <p style="color:pink">lovely</p> </div> <input type="text" i

  • JS实现数组去重,显示重复元素及个数的方法示例

    本文实例讲述了JS实现数组去重,显示重复元素及个数的方法.分享给大家供大家参考,具体如下: <script> var arr = ['土豆','土豆','茄子','土豆','茄子','土豆','紫红色']; function qc(arr){ var resultObj = {}; var result = []; var result2 = []; for(var i=0; i<arr.length; i++){ if(result.indexOf(arr[i]) == -1){ re

  • js中事件对象和事件委托的介绍

    Ie9以下浏览器中的事件对象是放在全局中的window.event; 解决兼容性:event = event || window.event 事件委托(就是将事件绑定到父级/爷爷级对象上,通过事件对象的target属性来控制子级对象的改变): event.target(点击的目标对象) <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <

随机推荐