js的对象与函数详解


Posted in Javascript onJanuary 21, 2019

一、对象

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

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

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();

js的对象与函数详解

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])
   }
  }

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

总结

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

Javascript 相关文章推荐
列表内容的选择
Jun 30 Javascript
jQuery EasyUI API 中文文档 - TreeGrid 树表格使用介绍
Nov 21 Javascript
Javascript的数组与字典用法与遍历对象的属性技巧
Nov 07 Javascript
jQuery+PHP实现动态数字展示特效
Mar 14 Javascript
JS实现点击按钮后框架内载入不同网页的方法
May 05 Javascript
Javascript中实现String.startsWith和endsWith方法
Jun 10 Javascript
当jquery ajax遇上401请求的解决方法
May 19 Javascript
JS常见创建类的方法小结【工厂方式,构造器方式,原型方式,联合方式等】
Apr 01 Javascript
微信小程序商城项目之侧栏分类效果(1)
Apr 17 Javascript
基于jQuery实现定位导航位置效果
Nov 15 jQuery
jQuery实现的老虎机跑动效果示例
Dec 29 jQuery
jQuery实现checkbox全选、反选及删除等操作的方法详解
Aug 02 jQuery
JS实现求5的阶乘示例
Jan 21 #Javascript
JS实现数组去重,显示重复元素及个数的方法示例
Jan 21 #Javascript
js中innerText/textContent和innerHTML与target和currentTarget的区别
Jan 21 #Javascript
Vue 表情包输入组件的实现代码
Jan 21 #Javascript
JS实现将对象转化为数组的方法分析
Jan 21 #Javascript
vue中过滤器filter的讲解
Jan 21 #Javascript
vue计算属性computed、事件、监听器watch的使用讲解
Jan 21 #Javascript
You might like
Discuz 6.0+ 批量注册用户名
2009/09/13 PHP
无法载入 mcrypt 扩展,请检查 PHP 配置终极解决方案
2011/07/18 PHP
php读取csv实现csv文件下载功能
2013/12/18 PHP
判断浏览器的javascript版本的代码
2010/09/03 Javascript
JavaScript 判断浏览器是否支持SVG的代码
2013/03/21 Javascript
intro.js 页面引导简单用法 分享
2013/08/06 Javascript
js 浏览本地文件夹系统示例代码
2013/10/24 Javascript
基于JQuery实现滚动到页面底端时自动加载更多信息
2014/01/31 Javascript
jquery默认校验规则整理
2014/03/24 Javascript
jQuery简单实现QQ空间点赞已经取消点赞
2015/04/02 Javascript
HTML5 JS压缩图片并获取图片BASE64编码上传
2020/11/16 Javascript
angular+bootstrap的双向数据绑定实例
2017/03/03 Javascript
详解Angular中的自定义服务Service、Provider以及Factory
2017/04/22 Javascript
详解vue组件通信的三种方式
2017/06/30 Javascript
浅析JavaScript中的特殊数据类型
2017/12/15 Javascript
关于vue面试题汇总
2018/03/20 Javascript
vue 2.5.1 源码学习 之Vue.extend 和 data的合并策略
2019/06/04 Javascript
一次让你了解全部JavaScript的作用域
2019/06/24 Javascript
vuex实现购物车功能
2020/06/28 Javascript
JavaScript实现京东快递单号查询
2020/11/30 Javascript
python实现html转ubb代码(html2ubb)
2014/07/03 Python
Python中装饰器兼容加括号和不加括号的写法详解
2017/07/05 Python
推荐8款常用的Python GUI图形界面开发框架
2020/02/23 Python
深入理解Tensorflow中的masking和padding
2020/02/24 Python
解决Django提交表单报错:CSRF token missing or incorrect的问题
2020/03/13 Python
如何实现在jupyter notebook中播放视频(不停地展示图片)
2020/04/23 Python
linux面试题参考答案(8)
2016/04/19 面试题
Java程序员面试题
2016/09/27 面试题
销售代表求职自荐信
2013/10/01 职场文书
3.12植树节活动总结2014
2014/03/13 职场文书
经典禁毒标语
2014/06/16 职场文书
写给老婆的保证书
2015/02/27 职场文书
学校艾滋病宣传活动总结
2015/05/09 职场文书
linux中nohup和后台运行进程查看及终止
2021/06/24 Python
警用民用对讲机找不同
2022/02/18 无线电
win10音频服务未响应怎么解决?win10音频服务未响应未修复的解决方法
2022/08/14 数码科技