猫史档案馆


【小鹰の代码课】第一期:对象的用法

用户:拉文克劳的小鹰拉文克劳的小鹰查看:22 回复:23 评论:22 创建时间:2022-05-01T18:45:54


大家好,我是小鹰

作为一名代码师&建筑师

只发建筑教程是不行滴()

以后,我会不定时发一下代码教程,希望对大家有帮助

对了

吉吉喵之前也发过对象的基本使用方法

大家可以去看看

————————————————————

第一期:对象的用法

1、对象的概念

2、对象的基本方法

3、对象的高级方法

now begin!

——————————————————————————————————

1、对象的概念

js作为一个面向对象的语言

对象是不可缺少的一部分

简单来说,对象是拥有属性和方法的数据

这可能听起来有些深奥

先别急,我来举个例子:

 

有一只鹰叫小鹰

那么它就会有许多的属性,比如毛色、拥有者、身高等

也会有一些方法,比如说话、飞行等

 

如果用js来描述,就会是

const ying = {
    '毛色':'red',
    '身高':50,
    '拥有者':'拉文克劳',
    '说话'(){
        world.say('嘤嘤婴')
    }
}

其中对象的属性和方法都放在大括号里,并用逗号分隔

这就是一个对象的定义方法

 

————————————————————————————

属性

对象通常用被认为是键值对的容器,或是一堆变量的集合

对象中的每一个属性都是一个键值对

用name:value的形式来表示

name为属性的名称,也可以理解成变量名,可以用引号括起来

value为属性的值,也可以理解为变量的值

这样说可能有些复杂,让我们用实际代码来看一看

const ying = {
    '毛色':'red',//一个键值对,也是一个属性
    '身高'/*name,一个键*/:50/*value,一个值*/,
    '拥有者':'拉文克劳'
}

 

那么,我们要如何访问对象的属性呢?

有两种方式:

const ying = {
    fur:'red',
    '身高':50,
    '拥有者':'拉文克劳'
}
console.log(ying['fur'])//red
console.log(ying.fur)//red

可以通过属性的键来获取属性的值

——————————————————————

方法

对象的方法其实是一个函数

 

比如

const ying = {
    speak(){
        world.say('嘤嘤婴')
    }
}

这里就定义了一个叫speak的函数,也是对象的一个方法

用函数构造的方式同样也可以定义方法

 

同样,也有两种方法可以调用方法

const ying = {
    speak(){
        world.say('嘤嘤婴')
    }
}
ying.speak()//嘤嘤婴
ying['speak']()//嘤嘤婴

通过定义对象,我们可以把需要操作的物品的信息等全都放在一起,方便调用

可以省去大量重复代码

 

js中几乎所有的事物都是对象

比如数组、字符串

代码岛中的entity也是对象

——————————————————————

2、对象的基本方法

 

1、修改

我们可以通过属性的键来修改属性的值

const ying = {
    fur:'red',
    '身高':50,
    '拥有者':'拉文克劳'
}
console.log(ying.fur)//red
ying.fur = 'white'
console.log(ying.fur)//white

修改的方法与变量的修改方法类似

必须要说明修改的键名

 

2、删除

可以用delete删除对象的属性

在delete后加上键名

const ying = {
    fur:'red',
    '身高':50,
    '拥有者':'拉文克劳'
}
console.log(Object.keys(ying)) //fur,身高,拥有者
delete ying['身高']
console.log(Object.keys(ying)) //fur,拥有者

 

3、查看所有属性的键

const ying = {
    fur:'red',
    '身高':50,
    '拥有者':'拉文克劳'
}
console.log(Object.keys(ying)) //fur,身高,拥有者
//Object.keys()返回对象中所有属性的键的数组

 

4、查看所有属性的值

const ying = {
    fur:'red',
    '身高':50,
    '拥有者':'拉文克劳'
}
console.log(Object.values(ying)) //red,50,拉文克劳
//Object.values()返回对象中所有属性的值的数组

 

5、增加属性

对一个对象已有的属性赋值为改,没有的属性赋值为增。

const ying = {
    fur:'red',
    '身高':50,
    '拥有者':'拉文克劳'
}
ying.attack = 100
console.log(ying.attack) //100

 

6、遍历对象

可以用for…in循环遍历

const ying = {
    fur:'red',
    '身高':50,
    '拥有者':'拉文克劳'
}
for(let key in ying){
    console.log(ying[key]) //red 50 拉文克劳
}

循环的变量为对象的每一个键

注意与for…of的区别:for…of为属性的值

遍历对象一般不用for…of

————————————————————————

3、对象的高级方法

前方高能!干货预警!

 

开始之前,先教大家一个查看对象的方法

JSON.stringify()

const ying = {
    fur:'red',
    '身高':50,
    '拥有者':'拉文克劳'
}
console.log(JSON.stringify(ying)) //{"fur":"red","身高":50,"拥有者":"拉文克劳"}

可以把对象转为字符串的形式,方便查看

 

1、this用法

在方法构造中,this指向方法所在的对象

使用this可以简化代码

const ying = {
    message:'嘤嘤婴',
    speak(){
        console.log(this.message)
    }
}
ying.speak() //嘤嘤婴

例子中的this就指向了方法所在的对象ying

学会活用this可以省去很多的打字时间

 

注意:this所指的对象为离所在方法最近的对象

 

2、Object用法

Object定义了许多方便的方法

 

(1)Object.assign()

这个方法可以合并对象,也就是把不同的源对象的属性复制到目标对象上,返回修改后的对象

const ying = {
    fur:'red',
    '身高':50,
    '拥有者':'拉文克劳'
}
const huan = {
    fur:'yellow',
    age:13,
    '拥有者':'赫奇帕奇'
}
console.log(JSON.stringify(ying)) //{"fur":"red","身高":50,"拥有者":"拉文克劳"}
Object.assign(ying/*目标对象*/, huan/*源对象*/)
console.log(JSON.stringify(ying)) //{"fur":"yellow","身高":50,"拥有者":"赫奇帕奇","age":13}
//Object.assign(target, …source)
//target为目标对象
//source为源对象
//可以有无数的源对象,但只能有一个目标对象

如果源对象中的属性具有和目标对象相同的键,则目标对象中的属性会被源对象中的属性覆盖

如果不同的源对象之间有相同的键,则会设置靠后的源对象

const ying = {
    fur:'red'
}
const huan = {
    fur:'yellow'
}
const data = {}
Object.assign(data, ying, huan)
console.log(data.fur) //yellow
//huan为靠后的源对象

可以添加无数多个源对象

 

(2)Object.is()

比较两个值是否相等,返回布尔值,类似于'==='

注:格式也要相等

const ying = {
    fur:'red',
    '身高':50,
    '拥有者':'拉文克劳'
}
const ying1 = {
    fur:'red',
    '身高':50,
    '拥有者':'拉文克劳'
}
console.log(Object.is(ying.fur, ying1.fur)) //true
//Object.is(value, value)
//value为要对比的值

 

(3)Object.entries()

这个方法可以返回一个数组

数组的每一项都是对象中可遍历属性的键值对数组

const ying = {
    fur:'red',
    '身高':50,
    '拥有者':'拉文克劳'
}
console.log(JSON.stringify(Object.entries(ying))) //[["fur","red"],["身高",50],["拥有者","拉文克劳"]]
//Object.entries(object)
//object为对象

 

(4)Object.hasOwnProperty()

Object为对象名

这个方法可以返回一个布尔值,表示对象是否有指定属性

如果指定的属性是对象的直接属性,则该方法返回 true

如果该属性是继承的或根本没有声明,则返回 false

const ying = {
    fur:'red',
    '身高':50,
    '拥有者':'拉文克劳'
}
console.log(ying.hasOwnProperty('fur')) //true
//Object.hasOwnProperty(key)
//Object为对象
//key为要查询的值名

 

还有一种方法:in

const ying = {
    fur:'red',
    '身高':50,
    '拥有者':'拉文克劳',
}
console.log('fur' in ying) //true
console.log('toString' in ying) //true

它与hasOwnProperty的区别就是

hasOwnProperty只判断对象的自身属性中包不包含所要查找的键名

而in操作符可以判断对象的自身属性以及它的原型链中包不包含所要查找的键名

具体可以上网查

 

(5)Object.fromEntries()

这个方法是Object.entries的逆操作

可以把Object.entries转换的数组转换为一个对象

const ying = {
    fur:'red',
    '身高':50,
    '拥有者':'拉文克劳'
}
let arr = Object.entries(ying)
console.log(JSON.stringify(arr)) //[["fur","red"],["身高",50],["拥有者","拉文克劳"]]
let ying1 = Object.fromEntries(arr)
console.log(JSON.stringify(ying1)) //{"fur":"red","身高":50,"拥有者":"拉文克劳"}
//Object.fromEntries(array)
//array为要转换的数组

利用这个方法,我们可以把map结构转为对象

 

(6)Object.freeze()

这个方法可以冻结一个对象,也就是让这个对象不可更改

const ying = {
    fur:'red',
    '身高':50,
    '拥有者':'拉文克劳'
}
console.log(ying.fur) //red
Object.freeze(ying)
ying.fur = 'white'
console.log(ying.fur) //red

 

3、对象的嵌套

对象内属性的值也可以是对象

访问对象中的对象的方法与访问普通对象的方法相同

const people = {
    ying:{
        fur:'red',
        '身高':50,
        '拥有者':'拉文克劳',
        speak(){
            console.log('嘤嘤')
        }
    },
    huan:{
        fur:'yellow',
        '身高':40,
        '拥有者':'赫奇帕奇',
    }
}
console.log(people.ying.fur) //red
people.ying.speak() //嘤嘤

 

——————————————————————

说了这么多,对象到底有什么用呢?

下面就让我来为大家举几个使用例子,来感受一下对象的强大

 

1、图鉴

/*版权归拉文克劳的小鹰所有*/
//*好像也没有什么难的()
const data = {
    '剑':{
        describe:'nb!',//内容
        op:['使用']//选项
    },
    '盾':{
        describe:'小鹰YYDS!',
        op:['使用']
    }
}
world.querySelectorAll('.book').forEach((e) => { //搜索所有带book标签的实体
    e.enableInteract = true;
    e.interactRadius = 4;
    e.interactHint = '图鉴'
    e.onInteract(async({entity}) => {
        const tip = await entity.player.dialog({
            type: Box3DialogType.SELECT,
            title: '图鉴',
            content: `这是一本图鉴`,
            options: Object.keys(data),   //data所有的键的名称
        });
        if (tip) {
            const a = await entity.player.dialog({
                type: Box3DialogType.SELECT,
                title: tip.value,
                content: data[tip.value].describe,   //每一条属性的描述
                options: data[tip.value].op,   //每一条属性的选项
            });
            if (a) {
                if(a.value == '使用'){ //点击选项后的效果
                    entity.player.directMessage(`你使用了${tip.value}`)
                }
            }
        }
    })
})

效果如下

center_image

center_image

你可以更改描述内容,加入你自己的创意

如果想要加入新的条目,只需要更改对象中的内容就行

 

这个例子,很好地体现了对象的便捷性

用对象把一系列的值封装在一起,用一段代码便可完成多个内容的展示

 

2、武器系统

/*版权归拉文克劳的小鹰所有*/
const data = {
    '剑':{
        async use(entity, raycast){
            const d = raycast.direction
            const knife = world.createEntity({ //创造弹药
                mesh: 'mesh/剑气.vb',
                position: entity.position,
                meshScale: new Box3Vector3(1 / 16, 1 / 16, 1 / 15),
                collides: true,
                gravity: false,
                meshOrientation: new Box3Quaternion(0, 0, 1, 0).rotateY(Math.atan2(d.z, d.x)),
            })
            knife.velocity.x += (raycast.direction.x * 2);//更改加速度
            knife.velocity.z += (raycast.direction.z * 2);
            knife.onEntityContact(({ other }) => {
                other.hurt(20)
            })
            await sleep(2000)
            knife.destroy() //不要忘了删除实体
        }
    },
}
world.onPlayerJoin(({entity}) => {
    entity.handThing = '剑'
})
world.onPress(({button, entity, raycast}) => {
    if(button == Box3ButtonType.ACTION0 && entity.handThing != '无'){
        data[entity.handThing].use(entity, raycast) //调用函数
    }
})

通过这段代码,可以实现左键发射子弹的效果

可以根据自己的需要在data中添加武器

注意,use为一个方法,如果里面要用到await,在前面要加上async

要想使用不同武器,要更改entity.handThing的值

还有,别忘了放上一个叫剑气的模型哦!

 

这段代码实际上是把函数封装在对象内,调用时只需要调取方法

省去了很多重复的代码,也使代码清晰明了

————————————————————————————————

这就是今天教程的全部内容了,大家可以自己多尝试,或是在网上搜索

会有更深刻的理解

理解最重要,不要盲目抄代码

——————————————————————————

小测试

下面为一个对象

const a = {
    a1:{
        name:'小鹰',
        message:'awa',
        play(){

        }
    }
}

请补充对象,并写出一段代码

使当点击右键时弹出对话框,显示a1的名字

并有说话、玩耍两个选项

当选择说话时,输出message的内容。当选择玩耍时,利用play方法,输出对象a的数组形式

做完后可以把代码发在评论区哦!

——————————————————————————

第一次做代码教程,可能会有些短

如有错误请指正

如有代码问题可以发在评论区

 

下期预告:

我也不知道要做什么()

大家可以在评论区说出想看什么教程()

 

end

 


回复

上一页1 页 / 共 1下一页
云游box3der尖头叉子云游box3der尖头叉子

啊哈,热乎乎的沙发()()()

点赞1


评论


云游box3der尖头叉子云游box3der尖头叉子

ddd

点赞0


评论


拉文克劳的小鹰拉文克劳的小鹰

ddd

点赞0


评论


用户_869149用户_869149

前排()因为您字数太多了看不完()但您真的是大佬!建筑牛的一批,不仅如此,发的代码教程还这么详细!顶顶顶()

点赞2


评论


该账号已被封禁该账号已被封禁

纠错

1.

const ying = {
    '毛色':'red',
    '身高':50,
    '拥有者':'拉文克劳',
    '说话'(){//这一行的'说话'不对 对象里定义的函数名只能是英文名
        world.say('嘤嘤婴')
    }
}

2.

const data = {
    '剑':{
        async use(entity, raycast){
            const d = raycast.direction
            const knife = world.createEntity({ //创造弹药
                mesh: 'mesh/剑气.vb',
                position: entity.position,
                meshScale: new Box3Vector3(1 / 16, 1 / 16, 1 / 15),
                collides: true,
                gravity: false,
                meshOrientation: new Box3Quaternion(0, 0, 1, 0).rotateY(Math.atan2(d.z, d.x)),
            })
            knife.velocity.x += (raycast.direction.x * 2);//更改加速度
            knife.velocity.z += (raycast.direction.z * 2);
            knife.onEntityContact(({ other }) => {
                other.hurt(20)
            })
            await sleep(2000)
            knife.destroy() //不要忘了删除实体
        }
    },
}
world.onPlayerJoin(({entity}) => {
    entity.handThing = '剑'
})
world.onPress(({button, entity, raycast}) => {
    if(button == Box3ButtonType.ACTION0 && entity.handThing != '无'){
        data[entity.handThing].use(entity, raycast) //调用函数
    }
})

(为什么前面不用const或global声明undefined/null='无')(恼)

点赞1


评论


FML饭米粒FML饭米粒

建议不要用a,a1这种变量名,不利于他人理解你的代码

点赞1


评论


友善的小黄鸡_漂流龙友善的小黄鸡_漂流龙

dddd

点赞0


评论


源码极客源码极客

好的,我以前还没发现对象里能有函数,涨知识了!

还有this用法讲的很好(反正我以前不懂,现在听懂了)

还有哦,催更建筑教程(bushi

点赞1


评论


企鹅vItY企鹅vItY

作品开头好黑啊,路都看不见,建议修改

点赞2


评论


yee089yee089

《我 是 搞 建 筑 的》()()

反正我是觉得这个纯语法的问题其实……还好()

下次搞点算法什么的,比如柏林噪音(bushi)

点赞1


评论


灵清帝王吃爆一切厕所灵清帝王吃爆一切厕所

收藏()

点赞1


评论


拉文克劳的小鹰拉文克劳的小鹰

带作持续测试中:https://box3.fun/e/8c2f9f38da700203265c,欢迎游玩并留下宝贵建议

点赞1


评论


AIfishyuanAIfishyuan

我只想要建筑课(划掉)建筑课代码课都想要

点赞0


评论


被窝哲学家a被窝哲学家a

哇瑟!!!!

嗯,就是,我在建一个霍格沃兹的地图,可以请你来帮我写代码吗(星星眼)

点赞0


评论


MC_TTMC_TT

回个复方便以后看(doge)

点赞1


评论


用户_869149用户_869149

催更()建筑教程()

点赞1


评论


马云编程猫马云编程猫

小鹰牛啊,学到了学到了imgsrc="https://static.cod喵/emoji/codemao/%E7%BC%96%E7%A8%8B%E7%8C%AB_%E7%82%B9%E8%B5%9E.gif"alt="emotion_编程猫_点赞"

点赞0


评论


冰玉ulb最后的呼吸冰玉ulb最后的呼吸

太棒了

点赞0


评论


tiger666250tiger666250

这是一个 奇 迹

 

小鹰在一篇教程只打了三个“()”

点赞1


评论


小树同学小树同学

你应该在小说写,一章一章方便我们找

点赞0


评论


Ezra__Ezra__

不讲一下

Object.create()

吗()

点赞0


评论


难起的名字难起的名字

ddd

点赞0


评论


yee剑走天下yee剑走天下

求助一下代码()

内个

值 in 对象名 和 对象名.has(值)有啥区别呢?

点赞1


评论