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 相关文章推荐
一个JQuery操作Table的代码分享
Mar 30 Javascript
jquery异步跨域访问代码
Jun 28 Javascript
jQuery ajax全局函数处理session过期后的ajax跳转问题
Jun 03 Javascript
javascript 常用验证函数总结
Jun 28 Javascript
AngularJS基础 ng-model 指令详解及示例代码
Aug 02 Javascript
Java  Spring 事务回滚详解
Oct 17 Javascript
浅析Jquery操作select
Dec 13 Javascript
基于jQuery插件jqzoom实现的图片放大镜效果示例
Jan 23 Javascript
vue注册组件的几种方式总结
Mar 08 Javascript
JS中async/await实现异步调用的方法
Aug 28 Javascript
vue-cli在 history模式下的配置详解
Nov 26 Javascript
vue实现单一筛选、删除筛选条件
Oct 26 Javascript
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 分页代码
2007/01/02 PHP
php switch语句多个值匹配同一代码块的实现
2014/03/03 PHP
PHP7新增运算符用法实例分析
2016/09/26 PHP
PHP实现超简单的SSL加密解密、验证及签名的方法示例
2017/08/28 PHP
PHP对称加密算法(DES/AES)类的实现代码
2017/11/14 PHP
Lazy Load 延迟加载图片的jQuery插件中文使用文档
2012/10/18 Javascript
一个封装js代码-----展开收起效果示例
2013/07/03 Javascript
javascript中数组中求最大值示例代码
2013/12/18 Javascript
express的中间件bodyParser详解
2014/12/04 Javascript
全面解析Angular中$Apply()及$Digest()的区别
2016/08/04 Javascript
js实现文字超出部分用省略号代替实例代码
2016/09/01 Javascript
jquery的父、子、兄弟节点查找,节点的子节点循环方法
2016/12/07 Javascript
学习使用Bootstrap栅格系统
2017/05/11 Javascript
Centos7 安装Node.js10以上版本的方法步骤
2019/10/15 Javascript
JS Web Flex弹性盒子模型代码实例
2020/03/10 Javascript
解决Vue-Router升级导致的Uncaught (in promise)问题
2020/08/07 Javascript
Python专用方法与迭代机制实例分析
2014/09/15 Python
跟老齐学Python之正规地说一句话
2014/09/28 Python
Python实现从脚本里运行scrapy的方法
2015/04/07 Python
Python根据区号生成手机号码的方法
2015/07/08 Python
Python爬虫实现全国失信被执行人名单查询功能示例
2018/05/03 Python
python引入不同文件夹下的自定义模块方法
2018/10/27 Python
pyqt5之将textBrowser的内容写入txt文档的方法
2019/06/21 Python
python交易记录链的实现过程详解
2019/07/03 Python
python opencv捕获摄像头并显示内容的实现
2019/07/11 Python
python 实现绘制整齐的表格
2019/11/18 Python
python 申请内存空间,用于创建多维数组的实例
2019/12/02 Python
解决pycharm 安装numpy失败的问题
2019/12/05 Python
深入理解HTML的FormData对象
2016/05/17 HTML / CSS
新加坡航空官方网站:Singapore Airlines
2016/10/13 全球购物
物业门卫岗位职责
2013/12/28 职场文书
电子专业毕业生自荐信
2014/05/25 职场文书
2016年七夕情人节宣传语
2015/11/25 职场文书
党员干部学法用法心得体会
2016/01/21 职场文书
小学五年级(说明文3篇)
2019/08/13 职场文书
IDEA中sout快捷键无效问题的解决方法
2022/07/23 Java/Android