From your objects array, you can create Map (lookup) which has keys as the name property and values as the negated version of the is property.
Map {
'a': true,
'b': true,
'c': true
}
You can then use this to lookup to filter your array of strings. If the Map has a value which is true then you can remove it from your array (by returning false), otherwise, if the Map doesn't have the current string, you can keep it in the array. Creating a map/object by preprocessing your objects array saves you from needing to use an inner loop inside of your filter(), improve the overall efficiency of your code if your array sizes increase.
const objects = [{name:'a',is:false},{name:'b',is:false},{name:'c',is:false}];
const strings = ['a','b','z','x'];
const lookup = new Map(objects.map(({name, is}) => [name, !is]));
const result = strings.filter(v => !lookup.get(v));
console.log(result);
Your approach was very close. However, the .includes() method doesn't accept a callback function like you're providing it with (.includes() will search your array for that same function object references your providing it with)
const cb = v => v; // fake callback
const arr = [cb]; // some array contains that callback
console.log(arr.includes(cb)); // providing the callback as a function to includes
// => true, as the `cb` function is inside of `arr`
If you want to provide your own "includes" logic, you can use .some() instead:
var objects = [{name:'a',is:false},{name:'b',is:false},{name:'c',is:false}];
var strings = ['a','b','z','x'];
let result = strings.filter(o1 => !objects.some(o2 => o2.name === o1));
console.log(result)
If you're curious, the above logic with .some() has a time complexity of O(N*M), whereas the Map approach has a time complexity of O(N+M), where N is the size of your strings array and M is the size of your objects array.