Javascript 面向对象编程(一):封装
创建对象三种方式
1.字面量的方式
var per1={ name:"沐风", age:20, sex:"男", eat:function () { console.log("吃"); }, readBook:function () { console.log(""); } };
2.调用系统的构造函数
var per2=new Object(); per2.name="沐风"; per2.age=30; per2.sex="男"; per2.eat=function () { console.log("吃"); }; per2.play=function () { console.log("玩"); };
3.自定义构造函数方式(推荐)
function Person(name,age,sex) { this.name=name; this.age=age; this.sex=sex; this.play=function () { console.log("天天打游戏"); }; } var per=new Person("沐风",18,"男"); console.log(per instanceof Person);
工厂模式
function createObject(name,age) { var obj=new Object(); obj.name=name; obj.age=age; obj.sayHi=function () { console.log("您好"); }; return obj; }
原型
1.构造函数方法很好用,但是存在一个浪费内存的问题
1 2 3 4 5 6 7 8 9 10 11 | function Cat(name, color) { this .name = name; this .color = color; this .type = "猫科动物" ; this .eat = function () { alert( "吃老鼠" ); }; } var cat1 = new Cat( "大毛" , "黄色" ); var cat2 = new Cat( "二毛" , "黑色" ); alert(cat1.type); // 猫科动物 cat1.eat(); // 吃老鼠 |
2.Prototype模式,所有实例的type属性和eat()方法,其实都是同一个内存地址,指向prototype对象,因此就提高了运行效率。
function Cat(name, color) { this.name = name; this.color = color; } Cat.prototype.type = "猫科动物"; Cat.prototype.eat = function () { alert("吃老鼠") }; var cat1 = new Cat("大毛", "黄色"); var cat2 = new Cat("二毛", "黑色"); alert(cat1.type); // 猫科动物 cat1.eat(); // 吃老鼠 alert(cat1.eat == cat2.eat); //true
简单的原型写法
Student.prototype = { //手动修改构造器的指向 constructor:Student, height: "188", weight: "55kg", study: function () { console.log("学习好开心啊"); }, eat: function () { console.log("我要吃好吃的"); } }; var stu=new Student("段飞",20,"男"); stu.eat(); stu.study(); console.dir(Student); console.dir(stu);
我们可以为系统的对象的原型中添加方法,相当于在改变源码
//我希望字符串中有一个倒序字符串的方法 String.prototype.myReverse=function () { for(var i=this.length-1;i>=0;i--){ console.log(this[i]); } }; var str="abcdefg"; str.myReverse();
回调函数
当我们将函数A传递给函数B,并由B来执行A时,A就成了一个回调函数(callback ftmctions)。如果这时A还是一个无名函数,我们就称它为匿名回调函数。
function FunA(a,b,callback) { return callback(a, b); } function FunB(a,b) { return a + b; } alert(FunA(1,2,FunB));
还可以用匿名函数代替FunB
function FunA(a,b,callback) { return callback(a, b); } alert(FunA(1,2,function(a,b){return a + b}));
自调函数
(function (name) { alert("我的名字是:"+name) })("mf")
缺点:无法重复利用
优点:不会产生任何全局变量,适合一次执行或初始化任务
如何把局部变量变成全局变量?
把局部变量给window就可以了
(function (win) { var num=10;//局部变量 //js是一门动态类型的语言,对象没有属性,点了就有了 win.num=num; })(window); console.log(num);
通过自调用函数产生一个随机数对象,在自调用函数外面,调用该随机数对象方法产生随机数
(function (window) { //产生随机数的构造函数 function Random() { } //在原型对象中添加方法 Random.prototype.getRandom = function (min,max) { return Math.floor(Math.random()*(max-min)+min); }; //把Random对象暴露给顶级对象window--->外部可以直接使用这个对象 window.Random=Random; })(window); //实例化随机数对象 var rm=new Random(); //调用方法产生随机数 console.log(rm.getRandom(0,5));
内部私有函数
var FunA = function (parmA) { var FunB = function (parmB) { return parmB * 2; } return "结果是:" + FunB(2); }
优点:有助于我们确保全局名字空间的纯净性,命名冲突的机会更小
私有性:可以选择将必要的函数暴露给外界,并保留属于自己的函数
返回函数的函数
var FunA = function () { alert("A"); return function () { alert("B"); }; } var A = FunA();//第一次输出A 返回的是函数引用,并不会产生函数调用 A();//第二次输出B
能重写自己的函数
function FunA() { alert("A"); //全局变量A被重新定义并被赋予新的函数 A= function () { alert("B"); }; } FunA();//第一次输出A A();//第二次输出B
闭包
1.闭包概念
作用域链
词法作用域
利用闭包突破作用域链
2.闭包的用途
Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。而反过来我们有时候需要得到函数内的局部变量,出于种种原因,正常情况下,这是办不到的,只有通过变通方法才能实现。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!